【问题标题】:Unity3D C# Object MovementUnity3D C# 对象移动
【发布时间】:2016-02-08 11:24:20
【问题描述】:

所以在脚本/编程方面我有点菜鸟,我需要一些帮助。目前,我将下面的脚本附加到球体中间的空游戏对象上。空对象有一个位于球体外侧的子立方体,因此当空对象旋转时,立方体沿球体外侧移动。

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

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

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

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

【问题讨论】:

  • 您是否尝试过为球体上的对象使用 CylinderCollider。
  • 我有,这就是目前的对撞机。
  • 好的,我明天看看吧
  • 谢谢,我真的不知道该怎么办
  • 我已经建立了一个测试项目,对我来说它正在停止,并且不会像你的那样旋转。虽然它会在 2 秒后穿过碰撞的物体 ^^。我注意到没有 CylinderCollider 但 Capsul Colliders,尝试增加你的胶囊的高度,所以这可能会解决你的第一个问题。

标签: c# unity3d


【解决方案1】:

一种方法是使用collision.relativeVelocity 或collision.contacts 来检测碰撞来自哪个方向,然后保存一些标志,如collidedLeft、collidedRight 等与您现在所做的类似的东西——更新时不要旋转如果其中一个标志为真,则在某个方向上。但是,它从某个角度出现了什么?你基本上需要实现整个物理系统。

我会建议一些不同的配置来实现这一点,它使用内置的物理引擎。

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

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

接下来,在inner 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
        }
    }
}

我创建了一个演示项目,您可以从我的 Dropbox 中获取它: https://www.dropbox.com/s/b1kjrax0repku48/SphereSampleProject.zip?dl=0

希望有帮助

【讨论】:

  • 感谢 Yura 的工作,但我似乎遇到了和以前一样的问题。当我按住向上箭头(如视频中所示)并且移动的立方体与另一个物体接触时,它只会慢慢地沿着对撞机向上移动并越过物体。我厌倦了下载你的演示项目,但是当我加载它时,它对我来说是一个空场景。也许我只是设置错了?这是一个视频,我向您展示了我对不同对象的所有设置:youtube.com/watch?v=m6Wg74Su6jc&feature=youtu.be
  • 奇怪的是打不开项目,你用的是什么版本的unity?我用 5.2 做到了。
  • 无论如何,我在您的视频中看到的内容是使用固定接头将 Wall 与 MiddleSphere 连接起来。他们不应该被养育——这就是导致这种跳跃运动的原因。你看,由于它们没有通过关节连接,unity 将它们视为两个不相关的对象,这就是为什么现在和你之前的视频中,Wall 都可以独立于 MiddleSphere 移动。你不想要它。所以你要做的不是让 Wall 成为 MiddleSphere 的子对象,而是转到 wall,添加一个组件 Fixed Joint,然后选择 MiddleSphere 作为连接体。我认为这就足够了。
  • 您先生,是那个人...非常感谢您的帮助!我得到了它的工作,并从中学到了很多东西。我也在使用 Unity 版本 5.0.0f,这可能是它打开一个空场景的原因。我正在考虑更新以尝试使用新的统一网络,但有一些其他项目想先完成。再次感谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-11-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多