【问题标题】:How to stop movement and/or rotation of a Unity gameObject如何停止 Unity 游戏对象的移动和/或旋转
【发布时间】:2019-11-07 23:57:44
【问题描述】:

我正在制作一个基于 Unity 的 Roll-A-Ball 教程的小游戏,尽管我没有使用过实际的教程。我加入了重生机制,但如果你在死时四处移动,那么在你重生后,你着陆后仍然有这种动力。我试图解决这个问题,但我不确定如何解决,因为我在使用 Unity 方面还是很陌生。我有一个视频显示:https://drive.google.com/open?id=1752bPBDVOe2emN_hmnlPaD4uaJQITpsP

这是处理重生的 C# 脚本:

public class PlayerBehavior : MonoBehaviour
{
    Rigidbody PlayerRB;
    public bool Dead;
    private int timer;
    public GameObject Particles;
    public bool InRespawn;

    void Update()
    {
        PlayerRB = GetComponent<Rigidbody>();
         if (Dead)
        {
            StartCoroutine("Respawn");
        }
    }

    IEnumerator Respawn()
    {
        InRespawn = true; //Used to prevent movement during respawn.
        PlayerRB.useGravity = false;
        transform.position = new Vector3(0, 4, 0);
        transform.rotation = new Quaternion(-80, 0, 0, 0); // Resets position.
        Dead = false;
        Instantiate(Particles, transform); // Adds respawn particle effect.
        yield return new WaitForSeconds(2);
        Destroy(this.gameObject.transform.GetChild(0).gameObject);
        PlayerRB.useGravity = true;
        PlayerRB.AddForce(0, 400, 0); // Does a little hop.
        InRespawn = false; // Tells the game that respawn is finished.
    }
}

【问题讨论】:

  • 这意味着如果dead变量在你死时为真
  • 将刚体的速度设置为空向量。
  • 而不是使用Update 来轮询状态,您应该实现这个更多的事件驱动并在将Dead 设置为true 的任何地方启动协程
  • @derHugo 我曾想过这样做,但我正计划制作陷阱和其他可能导致玩家重生的东西。我认为让他们更改变量会比启动协程更好,但老实说,我不知道哪个更好。
  • 好吧……你还是启动了一个协程;)

标签: c# unity3d


【解决方案1】:

重生时将刚体的速度归零:

IEnumerator Respawn()
{
    PlayerRB.velocity = Vector3.zero;

    // ... rest of method
}

作为旁注,您可能不需要在每一帧上运行GetComponent。这是一项昂贵的手术,因此最好尽量少做:

void Start()
{
    PlayerRB = GetComponent<Rigidbody>();
}


void Update()
{
     if (Dead)
    {
        StartCoroutine("Respawn");
    }
}

如果您想在玩家死亡时禁用与玩家的所有物理交互,您可以在此期间将其设置为运动学。请务必取消设置isKinematic,然后再对其施加强制。

IEnumerator Respawn()
{
    PlayerRB.isKinematic = true;

    // ... rest of method

    PlayerRB.isKinematic = false;

    PlayerRB.useGravity = true;
    PlayerRB.AddForce(0, 400, 0); // Does a little hop.
    InRespawn = false; // Tells the game that respawn is finished.
}

【讨论】:

  • 我将GetComponent 移至Start(),这看起来确实是个好主意。然而,当我输入PlayerRB.velocity = Vector3.zero; 时,它所做的只是稍微减慢了玩家的动力。当我按下某个键时,我尝试运行那条线,以便我可以看到如果我在移动时这样做会发生什么,但玩家只是放慢了速度;他们并没有完全停止,这就是我的目标。我还尝试使用for 循环以0.1 秒的延迟在它们之间运行几次线路,希望这会取消动力,但玩家仍然只是放慢了速度。我做错了吗?
  • @AMiller42 很难说没有看到你的运动代码.. 显然你一直在其他地方设置速度或 AddForce。为了确保您可以另外激活PlayerRB.isKinematic = true,并在以后再次允许移动时将其停用。
  • @derHugo 使用 isKinematic 效果很好!它给了我我一直在寻找的结果。您应该将其发布为我的问题的答案,以便我可以将其标记为已回答。
  • @derhugo,介意我编辑此答案以包含该解决方案吗?
  • @AMiller42 提醒一下,如果你确实设置了isKinematic,如果你有墙壁、电梯或平台之类的东西可以/应该在你死的时候推你,你赢了不能依靠物理引擎让他们这样做,您需要角色的移动代码或其他东西来检测它们并相应地移动。在问题中包含你的角色移动代码可能会更好,这样我们就可以用另一种方法来修复它,而不是在死亡期间使用isKinematic,否则玩家可能会因为死亡而越界(当然,除非这是有意的设计选择)
【解决方案2】:

像这样在你的代码中创建一个布尔值

bool isDead=false;

然后在你死的时候让它成为现实 将其添加到您的更新中

if(isDead){
rb.velocity=vector3.zero;
}

如果它死了,这会阻止你的物体移动

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多