所以我在编写脚本/编程时有点像菜鸟,我需要一些帮助。目前我将下面的脚本附加到一个位于球体中间的空游戏对象。空对象具有位于球体外部的子立方体,因此当空对象旋转时,立方体沿着球体的外部移动。
我的问题出现在那个立方体与球体外部的任何其他不可移动物体接触时,它会移动并围绕该物体旋转,这是我不想要的。我想要的是立方体停止在不可移动物体的方向上移动但能够向左/向右/向后移动。我已经编写了代码,当多维数据集与不可移动的对象接触时,它会停止旋转空游戏对象的脚本,但之后我再也无法移动空游戏对象......它只是冻结在那里。这是我的剧本。
这是附加到空游戏对象的脚本
public class SphereMotor : MonoBehaviour {
public Vector3 eulerAngleVelocity;
public Rigidbody rb;
private float speed = 45.0f;
public bool collided = false;
public float turnSpeed = 45.0f;
void Start()
{
rb = GetComponent<Rigidbody>();
}
public void Collided()
{
collided = true;
}
public void NotCollided()
{
collided = false;
}
void Update()
{
if (Input.GetKey(KeyCode.LeftArrow) && !collided) {
transform.Rotate (0.0f, turnSpeed * Time.deltaTime, 0.0f);
}
if (Input.GetKey(KeyCode.RightArrow) && !collided) {
transform.Rotate (0.0f, -turnSpeed * Time.deltaTime, 0.0f);
}
if (Input.GetKey(KeyCode.UpArrow) && !collided) {
transform.Rotate (turnSpeed * Time.deltaTime, 0.0f, 0.0f);
}
if (Input.GetKey(KeyCode.DownArrow) && !collided) {
transform.Rotate (-turnSpeed * Time.deltaTime, 0.0f, 0.0f);
}
}
这是碰撞的脚本
herebool isColliding = false;
public SphereMotor _SphereMotor;
void Start()
{
_SphereMotor = GameObject.FindObjectOfType<SphereMotor>();
}
void OnCollisionEnter(Collision collision)
{
if(collision.gameObject.tag == "Player")
{
//isColliding = true;
StartCoroutine(ObjectColliding());
Debug.Log("wall hit");
}
}
void OnCollisionExit(Collision collision)
{
if(collision.gameObject.tag == "Player")
{
isColliding = false;
}
}
public IEnumerator ObjectColliding()
{
isColliding = true;
yield return new WaitForSeconds(2f);
isColliding = false;
}
void Update()
{
if(isColliding == true)
_SphereMotor.Collided();
if(isColliding == false)
_SphereMotor.NotCollided();
}
以下是展示我的问题的视频:https://www.youtube.com/watch?v=tkbbiTwkTqA
我尝试使用Coroutine来尝试修复问题,但它并没有真正起作用。当我按住其中一个移动按钮时,立方体仍然围绕不可移动的物体旋转。我真的不知道如何处理这个问题所以任何建议都会非常感激!
答案 0 :(得分:0)
一种方法是使用collision.relativeVelocity或collision.contacts来检测碰撞的方向,然后保存一些标志,如collidedLeft,collidedRight,以及类似于你现在所做的事情 - 更新时不要旋转如果其中一个标志为真,则在某个方向上。但那么,从某种角度来看它是什么?你基本上需要实现整个物理系统。
我建议使用一个不同的配置来实现这一点,它使用内置的物理引擎。
首先,对影响刚体的对象使用transform.rotation通常是一种不好的做法,因为它需要额外的计算。最好在FixedUpdate中直接使用刚体。
现在,内球和立方体都是刚体。我们不需要重力或角度阻力。而不是为它们提供父母,更好的方法是使用固定关节连接它们。
接下来,在内部法术的刚体属性中,使其位置固定在X,Y和Z轴上(我们希望它只旋转,而不是移动)。
立方体需要一个对撞机。内心没有。 现在你只需要SphereMotor,根本不需要碰撞处理,所有这些都是由刚体完成的。代码与您的代码非常相似,只是操纵刚体速度而不是手动操作:
using UnityEngine;
public class SphereMotor : MonoBehaviour {
public Rigidbody rb;
public float turnSpeed = 45.0f;
void Start()
{
rb = GetComponent<Rigidbody>();
}
void FixedUpdate()
{
rb.freezeRotation = false;
if (Input.GetKey(KeyCode.LeftArrow)) {
// Unity measures angular velocity in radians
rb.angularVelocity = new Vector3(0.0f, turnSpeed*Mathf.Deg2Rad, 0.0f);
} else if (Input.GetKey(KeyCode.RightArrow)) {
rb.angularVelocity = new Vector3 (0.0f, -turnSpeed*Mathf.Deg2Rad, 0.0f);
} else if (Input.GetKey(KeyCode.UpArrow)) {
rb.angularVelocity = new Vector3 (turnSpeed*Mathf.Deg2Rad, 0.0f, 0.0f);
} else if (Input.GetKey(KeyCode.DownArrow)) {
rb.angularVelocity = new Vector3 (-turnSpeed*Mathf.Deg2Rad, 0.0f, 0.0f);
} else {
rb.freezeRotation = true; // No key pressed - stop
}
}
}
我创建了一个演示项目,您可以从我的Dropbox中获取它: https://www.dropbox.com/s/b1kjrax0repku48/SphereSampleProject.zip?dl=0
希望有所帮助