C# 在unity3d上进行正确的Z字形移动有什么步骤吗

C# 在unity3d上进行正确的Z字形移动有什么步骤吗,c#,unity3d,C#,Unity3d,基本上我想在2d上做一个Z字形的自上而下的运动,我在添加(input.getmousebuttondown(0))时遇到了一个问题,它总是闪烁,而不是我想要的 public float frequency = 10f; public float magnitude = 5f; public float speed = 10f; float percentage = 0; Vector3 pos; Vector3 axis; public Rigidbody2D rb2d; // Start

基本上我想在2d上做一个Z字形的自上而下的运动,我在添加
(input.getmousebuttondown(0))
时遇到了一个问题,它总是闪烁,而不是我想要的

public float frequency = 10f;
public float magnitude = 5f;
public float speed = 10f;
float percentage = 0;

Vector3 pos;
Vector3 axis;

public Rigidbody2D rb2d;

// Start is called before the first frame update
void Start()
{
    pos = transform.position;
    axis = transform.right;
}

// Update is called once per frame
void Update()
{
    Movement();
}

public void Movement()
{
    pos += Vector3.up * Time.deltaTime * speed;
if(Input.GetMouseButtonDown(0)){
transform.position = pos + axis * Mathf.Sin(Time.time * frequency) * magnitude;
}
还有,我想在照片上看到这样的机械装置,

所以当我轻拍球时,球会呈之字形移动,但如果我不轻拍球,就朝着正确的方向移动,如图所示

就像我的意思一样,

你的
Movement()
函数只运行一次,因为你基本上是说,“单击时运行这个函数”,如果你想让这个函数运行每一帧(我假设,因为你把它放在
Update()
),你必须单击每一帧,这是不可能的

当用户单击并在另一个功能中移动对象时,如果没有任何
if
条件,请尝试仅更改对象的目标

像这样:

Update(){
       Movement();
       ChangeDirection();
    }
    
    void Movement(){
      //move object every frame without any conditions. Don't use GetMouseButtonDown() here****
    }
    
    void ChangeDirection(){
      if(GetMouseButtonDown(0)){
//Change the direction of object. For example, if it currently goes to the 
//left, set the direction to the right. Because your Movement() works every
//frame, just changing the direction to the opposite is will be enough.
        }
    }

如果你想创造一个锯齿形的效果,你可以去看看。

我猜你想要的是这样的逻辑:

begin run:
direction = straight
ready player one

screen tapped:
if direction == straight, direction = right
if direction == right, direction = left
if direction == left, direction = right
// (or whatever logic you prefer)

each frame:
1. move the ball appropriately for "direction"
2. collision with walls/etc?
     if direction == right, direction = left
     if direction == left, direction = right
2. collision with keepers?
     run is over
“direction”需要一个状态变量,它可能是“left”或“right”。看起来你也想要“直”

您的逻辑如下所示:

begin run:
direction = straight
ready player one

screen tapped:
if direction == straight, direction = right
if direction == right, direction = left
if direction == left, direction = right
// (or whatever logic you prefer)

each frame:
1. move the ball appropriately for "direction"
2. collision with walls/etc?
     if direction == right, direction = left
     if direction == left, direction = right
2. collision with keepers?
     run is over
我很确定这就是你想要的逻辑


同样的秘密是,你需要一个状态来确定方向,切换它的奇偶性(或游戏中正确的任何东西)。

据我所知,当玩家点击屏幕时,你希望球呈之字形-突然改变水平方向

要做到这一点,首先你必须了解什么是速度。在这种情况下,在这个二维世界中,速度由垂直和水平运动组成。换句话说,有一个向量在水平方向(左或右)拉动,有一个向量在垂直方向(上或下)拉动

所以,你可以把球的速度分解成x和y分量

public float magnitude = 5f;
public float forwardSpeed = 10f;
public float horizontalSpeed = 10f;

private Vector2 horizontalAxis;

private void Start()
{
    horizontalAxis = Vector2.right;
}

private Vector2 GetCompositeVelocity()
{
    Vector2 forward = Vector2.up * forwardSpeed;
    Vector2 horizontal = horizontalAxis * horizontalSpeed;
    Vector2 composite = forward + horizontal;

    return Vector2.Clamp(composite, magnitude);
}
如您所见,
水平轴
在游戏开始时设置为正确的方向。我们需要根据用户的输入进行更改。这是怎么做的

首先,我们引入一个求反向量,这样我们就可以乘以水平轴向量得到它的对方向。也就是说,当它指向右边时,将它乘以否定子,使它指向左边。这很简单

private Vector2 negationVector;

private void Start()
{
    horizontalAxis = Vector2.right;
    negationVector = new Vector2(-1f, 0);
    // You can also write the above as negationVector = Vector2.Left. They're the same thing.
}

private void OnMouseDown()
{
    horizontalAxis *= negationVector;
    // E.g. (1, 0) * (-1, 0) = (-1, 0). Then, next time, (-1, 0) * (-1, 0) = (1, 0).
}
最后,当用户改变速度时,我们必须更新速度

private void OnMouseDown()
{
    horizontalAxis *= negationVector;
    UpdateVelocity();
}

private void UpdateVelocity()
{
    Vector2 velocity = GetCompositeVelocity();
    rb2d.velocity = velocity;
}
别忘了,我们需要在游戏开始时更新速度。此外,我会将用于初始化
水平轴
否定向量
的代码移动到
唤醒()
,这是在
开始()之前调用的。你不必这么做,但这是一个很好的练习

private void Awake()
{
    horizontalAxis = Vector2.right;
    negationVector = new Vector2(-1f, 0);
}

private void Start()
{
    UpdateVelocity();
}
如果您想从非
OnMouseDown()
的方法中执行此操作,最好将改变方向的逻辑提取到一个单独的方法中

总的来说,我们得到了这个:

public float magnitude = 5f;
public float forwardSpeed = 10f;
public float horizontalSpeed = 10f;

private Vector2 horizontalAxis;
private Vector2 negationVector;

public Rigidbody2D rb2d;

private void Awake()
{
    horizontalAxis = Vector2.right;
    negationVector = new Vector2(-1f, 0);
}

private void Start()
{
    UpdateVelocity();
}

private void OnMouseDown()
{
    ReverseHorizontalVector();
    UpdateVelocity();
}

private void ReverseHorizontalVector()
{
    horizontalAxis *= negationVector;
}

private void UpdateVelocity()
{
    Vector2 velocity = GetCompositeVelocity();
    rb2d.velocity = velocity;
}

private Vector2 GetCompositeVelocity()
{
    Vector2 forward = Vector2.up * forwardSpeed;
    Vector2 horizontal = horizontalAxis * horizontalSpeed;
    Vector2 composite = (forward + horizontal);

    return Vector2.Clamp(composite, magnitude);
}

如果您希望在球与某物(如墙)碰撞时发生某种情况,可以在内部或外部执行此操作。这一点的实现超出了本问题的范围,但您可以在提供的链接中看到示例(指向官方文档)

你想让球自动跳出墙壁,但在敲击时也会突然切换方向吗?是的,像往常一样,你还可以用物理来做吗?你说的轻拍很容易,你是说“当我轻拍的时候,它会改变方向”还是说“在我按住它的时候,它会Z字形”呢。游戏编程既困难又微妙。我不明白这意味着
当用户单击并在另一个函数中移动对象时,在没有任何if条件的情况下尝试只更改对象的目的地。
,你能用脚本解释一下吗问题是我的脚本在
pos+=Vector3.up*Time.deltaTime*speed;变换位置=位置+轴*数学正弦(时间*频率)*幅值它已经在乒乓球上了,所以它在第一次跑步时会曲折前进,我不想这样做