Unity3D C#物体运动

Unity3D C#物体运动,c#,unity3d,C#,Unity3d,因此,当涉及到脚本编写/编程时,我有点不在行,我需要一些帮助。目前,我有下面的脚本附加到一个空的游戏对象,在一个球体的中间。空对象具有位于球体外部的子立方体,因此当空对象围绕球体旋转时,立方体将沿球体外部移动 我的问题是,当立方体与球体外部的任何其他不可移动的物体接触时,它会围绕这个物体移动和旋转,这是我不想要的。我想要的是立方体停止向不可移动物体的方向移动,但能够向左/向右/向后移动。我已经编写了代码,当立方体接触到不可移动的对象时,它会停止旋转空游戏对象的脚本,但是我再也不能移动空游戏对象了

因此,当涉及到脚本编写/编程时,我有点不在行,我需要一些帮助。目前,我有下面的脚本附加到一个空的游戏对象,在一个球体的中间。空对象具有位于球体外部的子立方体,因此当空对象围绕球体旋转时,立方体将沿球体外部移动

我的问题是,当立方体与球体外部的任何其他不可移动的物体接触时,它会围绕这个物体移动和旋转,这是我不想要的。我想要的是立方体停止向不可移动物体的方向移动,但能够向左/向右/向后移动。我已经编写了代码,当立方体接触到不可移动的对象时,它会停止旋转空游戏对象的脚本,但是我再也不能移动空游戏对象了……它只是冻结在那里。这是我的剧本

这是附加到空游戏对象的脚本

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);        
    }
}
公共类SphereMotor:MonoBehavior{
公共矢量3欧拉速度;
公共刚体;
私人浮动速度=45.0f;
公共布尔碰撞=错误;
公共浮子转速=45.0f;
void Start()
{
rb=GetComponent();
}
公共空间冲突()
{
碰撞=真;
}
公共无效不冲突()
{
碰撞=错误;
}
无效更新()
{
if(Input.GetKey(KeyCode.LeftArrow)&&!冲突){
变换旋转(0.0f,转速*时间增量,0.0f);
}
if(Input.GetKey(KeyCode.RightArrow)&&!冲突){
变换旋转(0.0f,-转速*时间增量,0.0f);
}
if(Input.GetKey(KeyCode.UpArrow)&&!冲突){
变换旋转(转速*时间增量,0.0f,0.0f);
}
if(Input.GetKey(KeyCode.DownArrow)&&!冲突){
变换旋转(-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();

}
herebool isColliding=false;
公共SphereMotor_SphereMotor;
void Start()
{
_SphereMotor=GameObject.FindObjectOfType();
}
无效碰撞中心(碰撞)
{
如果(collision.gameObject.tag==“Player”)
{
//isColliding=true;
start例程(objectcolling());
Log(“撞墙”);
}
}
void OnCollisionExit(碰撞)
{
如果(collision.gameObject.tag==“Player”)
{
isColliding=假;
}
}
公共IEnumerator对象冲突()
{
isColliding=true;
产生返回新的WaitForSeconds(2f);
isColliding=假;
}
无效更新()
{
如果(isColliding==true)
_SphereMotor.collide();
如果(isColliding==false)
_SphereMotor.notcollide();
}
下面是一段视频,展示了我在行动中遇到的问题:


我试着用一个协同程序来解决这个问题,但它并没有真正起作用。当我按下一个移动按钮时,立方体仍然围绕着不可移动的物体旋转。我真的不知道如何解决这个问题,所以任何建议都会非常感谢!

一种方法是使用collision.relativelocity或collision.contacts要检测碰撞来自哪个方向,然后保存一些标志,如CollidateLeft、CollidateRight,以及类似于您现在所做的操作-更新时,如果其中一个标志为真,则不要在某个方向上旋转。但是,从某个角度来看,它是什么?您基本上需要实现整个物理系统

我建议使用一种不同的配置来实现这一点,即使用内置的物理引擎

首先,在影响刚体的对象上使用transform.rotation通常是一种不好的做法,因为它需要额外的计算。最好在FixedUpdate中直接使用刚体

现在,内部球体和立方体都是刚体。我们不需要重力或角阻力。与其作为它们的子对象,更好的方法是使用固定关节将它们连接起来

接下来,在内部spere的刚体属性中,将其位置固定在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
        }
    }
}
使用UnityEngine;
公共类SphereMotor:单行为{
公共刚体;
公共浮子转速=45.0f;
void Start()
{
rb=GetComponent();
}
void FixedUpdate()
{
rb.1=假;
if(Input.GetKey(KeyCode.LeftArrow)){
//Unity以弧度度量角速度
rb.angularVelocity=新矢量3(0.0f,转速*Mathf.Deg2Rad,0.0f);
}else if(Input.GetKey(KeyCode.RightArrow)){
rb.angularVelocity=新矢量3(0.0f,-旋转速度*Mathf.Deg2Rad,0.0f);
}else if(Input.GetKey(KeyCode.UpArrow)){
rb.angularVelocity=新矢量3(转速*Mathf.Deg2Rad,0.0f,0.0f);
}else if(Input.GetKey(KeyCode.DownArrow)){
rb.angularVelocity=新矢量3(-turnSpeed*Mathf.Deg2Rad,0.0f,0.0f);
}否则{
rb.freezeRotation=true;//未按任何键-停止
}
}
}
我创建了一个演示项目,您可以从我的dropbox中获得:


希望这有帮助,一种方法是使用collision.relativeVelocity或collision.contacts来检测碰撞来自哪个方向,然后保存一些标志,如CollideLeft、CollideRight等,类似于您现在所做的操作-更新时,如果其中一个标志为真,则不在某个方向旋转。但是,接下来,它会发生什么呢从某个角度看,你基本上需要实现整个物理系统

我建议使用一种不同的配置来实现这一点,即使用内置的物理引擎

首先,在上使用transform.rotation通常是一种不好的做法