답변:
Unity 물리 엔진의 중력은 한 방향으로 만 진행되며 편집-> 프로젝트 설정 메뉴의 물리 메뉴에서 제어됩니다.
그 이외의 다른 일을하려면 자신의 중력을 구현해야합니다.
기본적으로, 무게 중심이되고 싶은 물체에 구체 충돌체를 추가 할 수 있습니다. 충돌체는 물체의 중력에 의해 물체가 영향을 받으려는 전체 영역을 포함해야합니다. 물체가이 "영구 영역"과 충돌 할 때마다 물체에 힘을가합니다. 영향력의 영역 안에있는 한 계속해서 힘을가합니다.
사용하는 중력 상수는 사용자가 조정할 수 있지만 실제 세계에서 계산에 사용되는 표준 상수는 다음과 같습니다.
F = Gm1m2 / r2
그 철자법은 다음과 같습니다.
힘 = 중력 상수 * 물체 1의 질량 * 물체 2의 질량 / 두 물체 사이의 거리 제곱.
중력 상수는 9.81이 아닙니다. 그것이 지구 표면의 중력에 의한 가속입니다.
중력 방정식에 의지 할 필요가 없습니다. 중력으로 인한 가속은 질량에 관계없이 일정하므로 작은 물체를 각 프레임마다 큰 물체로 가속하기 만하면됩니다.
코드는 다음과 같습니다.
public void FixedUpdate()
{
rigidbody.velocity += gravitationalAcceleration * Time.fixedTime * (largeObject.transform.position - transform.position);
}
사실, 저는 현재 중력에 기초한 게임을 진행하고 있습니다. 간단히 말해서, 당신은 타원형 궤도와 새총 효과를 통해 플레이어를 움직일 수 있습니다. 중력을 비활성화 하고이 코드를 사용했습니다.
using UnityEngine;
using System.Collections;
public class PlanetGrav : MonoBehaviour {
//Declare Variables:
//Strength of attraction from your sphere (obviously, it can be any type of game-object)
public float StrengthOfAttraction;
//Obviously, you won't be using planets, so change this variable to whatever you want
GameObject planet;
//Initialise code:
void Start ()
{
//Again, you can change the tag to whatever you want.
planet = GameObject.FindGameObjectWithTag("Planet");
}
//Use FixedUpdate because we are controlling the orbit with physics
void FixedUpdate () {
//Declare Variables:
//magsqr will be the offset squared between the object and the planet
float magsqr;
//offset is the distance to the planet
Vector3 offset;
//get offset between each planet and the player
offset = planet.transform.position - transform.position;
//My game is 2D, so I set the offset on the Z axis to 0
offset.z = 0;
//Offset Squared:
magsqr = offset.sqrMagnitude;
//Check distance is more than 0 to prevent division by 0
if (magsqr > 0.0001f)
{
//Create the gravity- make it realistic through division by the "magsqr" variable
rigidbody2D.AddForce((StrengthOfAttraction * offset.normalized / magsqr) * rigidbody2D.mass);
}
}
}
}
PS 코드는 원래 모든 행성의 배열을 반복했습니다.이 코드는 편집되었으므로 완전히 정확하지 않을 수 있습니다. 그래도 괜찮을 것입니다.
나는 Zero-G에 기반을 둔 유사한 프로젝트를 진행하고 있는데, 여기에는 부피, 밀도, 질량, 에너지 및 전도도에 따라 중력 및 전자기력을 생성하고 반응하는 모든 게임 개체가 필요합니다. 나는 스크립팅을 처음 접했지만 3D 공간에서 중력에 관한 한 거의 작동하도록 위의 스크립트를 약간 수정했습니다.
using UnityEngine;
using System.Collections;
public class DynamicWeightAnalysis : MonoBehaviour {
//Declare Variables:
//BBB adding volume calculations
//NOPE
//BBB adding density (...does nothing yet...)
public float density;
//BBB NOPE!
//Strength of attraction from your game-object, ideally this will be derived from a calculation involving the objects volume and density, but for now it's entered from the inspector)
public float RelativeWeight;
//BBB Here, we name our target object (s)
GameObject blockALPHA;
//Initialise code:
void Start ()
{
//BBB here, we define our target object by searching for its tag (setup in editor)
blockALPHA = GameObject.FindGameObjectWithTag("Block ALPHA");
}
//Use FixedUpdate because we are controlling the orbit with physics
void FixedUpdate () {
//Declare Variables:
//magsqr will be the offset squared between the object and the planet
float magsqr;
//offset is the distance to the planet
Vector3 offset;
//get offset between each planet and the player
offset = blockALPHA.transform.position - transform.position;
//Offset Squared:
magsqr = offset.sqrMagnitude;
//Check distance is more than 1 to prevent division by 0 (because my blocks are all 1x1x1 so, any closer than 1 and they'd be intersecting)
if (magsqr > 1f)
{
//Create the gravity- make it realistic through division by the "magsqr" variable
GetComponent<Rigidbody>().AddForce((RelativeWeight * offset.normalized / magsqr) * GetComponent<Rigidbody>().mass);
}
}
}
보시다시피, 나는 여전히 작업 중입니다. 기본적으로 지금까지 "BBB"로 주석이 달린 모든 추가 사항은 아직 원하는대로 작동하지 않습니다. 그러나 그것이 의미하는 바와 같이, 그것은 나의 "블록 알파"객체들이 3d에서 다른 "블록 알파"객체들과 상당히 예측 가능한 방식으로 중력 적으로 상호 작용할 수있게한다. (두 개 이상의 블록을 배치 할 때 마지막 블록은 항상 "유인 자"이며 충돌이 발생할 때까지 정지 상태로 유지됩니다.
특정 평면에 대해 중력을 변경하려면이 스크립트를 평면에 부착 할 수 있습니다.
using UnityEngine;
public class ChangeGavityToThisObject : MonoBehaviour
{
private Quaternion rot;
private Vector3 gravityValue;
void Start()
{
gravityValue = Physics.gravity;
}
void Update()
{
rot = GetComponent<Transform>().rotation;
Physics.gravity = rot * gravityValue;
}
}
게임에서이 평면의 회전을 변경할 수 있기를 원하기 때문에 GetComponent가 업데이트 중입니다.