【问题标题】:My Player Movement is presenting some Issues我的玩家运动出现了一些问题
【发布时间】:2020-09-22 18:22:58
【问题描述】:

我开始使用 Unity 学习 C#,我猜我的代码存在一些问题,我的播放器的移动工作正常但不是那么好。让我解释一下,我在屏幕底部有一个玩家,它只能自己从左到右移动,使用 transform.translate (我没有使用刚体),因为在与侧面碰撞时它会停止,并且不是常数运动,想法是,一旦与侧面发生碰撞,它就会改变方向,但速度相同。

当玩家与墙壁碰撞时会出现问题(移除了网格渲染器以保持它们透明)但如果同时按下键来触发方向的改变,玩家会卡在角落,如图所示在这个 gif 示例中:

等待播放器卡在角落,gif 大约需要 15 秒。

这是我的实际播放器脚本

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PMovement : MonoBehaviour
{

public float playerSpeed = 8.0f;

void Update()
{
    float moveX = playerSpeed * Time.deltaTime;

    transform.Translate(moveX, 0, 0);

    if (Input.GetKeyUp(KeyCode.Space))
    {
        playerSpeed = playerSpeed * -1;
    }

}

void OnCollisionEnter(Collision target)
{
    if (target.gameObject.tag.Equals("SideWalls") == true)
    {
        playerSpeed = playerSpeed * -1;
    }
}
}

【问题讨论】:

    标签: c# unity3d


    【解决方案1】:

    您的代码看起来很适合您想要实现的目标。不幸的是,在 Unity 中可能不足以准确指出问题,因为代码很大程度上取决于编辑器的设置。此问题或类似问题的一种可能解决方案:

    如果您仍然有阻塞碰撞器,(碰撞功能需要某种刚体。),或者如果您固定玩家的位置以阻止溢出,则可能会发生以下情况:

    • 右侧的对撞机被击中
    • 玩家方向向左转
    • 空间被击中而对撞机仍在接触
    • 玩家方向再次向右转
    • 右侧左侧没有碰撞器可再次启动 colliderEnter 事件。

    在这种情况下,当玩家触摸一侧时会阻止您的空间识别。

    【讨论】:

    • 我试过了,但是没有用} } void OnCollisionExit(Collision target) { if (target.gameObject.tag.Equals("SideWalls")) { if (Input.GetKeyUp(KeyCode.Space)) { ToiletteSpeed = ToiletteSpeed * -1; } } }
    • 有没有办法通过速度或 AddForce 以恒定的运动来做到这一点?没有减速? @AyJayKay
    • enter 和 exit 方法在退出或进入的帧中被调用一次。您可以使用 OnCollisionStay 并保存标志 isTouching 或其他东西。您需要在更新循环中抑制空间识别,而不是在对撞机方法之一上。
    【解决方案2】:

    如果你在撞墙时改变了方向,但在正确的时间按下了空格键,那么你很可能最终会进入墙内。然后它会一直认为它正在进入墙壁碰撞并一遍又一遍地反转方向。这就是我要做的。

    public class PMovement : MonoBehaviour
    {
    
    private List<GameObject> Collisions = new List<GameObject>();
    public float playerSpeed = 8.0f;
    
    void Update()
    {
        float moveX = playerSpeed * Time.deltaTime;
    
        transform.Translate(moveX, 0, 0);
    
        if (Collisions.Count <= 0 && Input.GetKeyUp(KeyCode.Space))
        {
            playerSpeed = playerSpeed * -1;
        }
    
    }
    
    void OnCollisionEnter(Collision target)
    {
        if (!Collisions.Contains(target.gameObject) && target.gameObject.tag.Equals("SideWalls") == true)
        {
            Collisions.Add(target.gameObject);
            playerSpeed = playerSpeed * -1;
        }
    }
    
    
    void OnCollisionExit(Collision target)
    {
        if (Collisions.Contains(target.gameObject)) {
            Collisions.Remove(target.gameObject);
        }
    }
    }
    

    通过保留您所在的墙对象的列表,如果您在墙内,则可以禁用空格键。请记住,可能有更好的方法来做您正在做的事情,但这应该可以解决您目前遇到的问题。

    【讨论】:

    • 我相信有一个错字:你不能两次定义相同的方法。 :) 如果你的意思是从列表中删除时退出:关键是省略空格输入,是的,但不是因为来回触发方向改变:当碰撞体接触时,不会每帧调用 enter 和 exit 方法。
    • 是的,这是一个错字。我也知道只有在进入时才调用 enter ,而只有在退出时才调用 exit 。但是,如果玩家与墙壁碰撞,改变方向,然后在碰撞完全退出之前再次击中空间以改变方向,那么根据墙壁碰撞器的设置方式,他们可能会卡在墙。可以使用 OnCollisionEnter 中的调试日志轻松测试。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-10-18
    • 2023-01-02
    • 1970-01-01
    • 2021-08-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多