Unity:对角线移动问题
Unity: Diagonal movement issue
我有一个测试 2D 游戏,我的玩家从左向右移动,当他到达屏幕的尽头时,它只会在另一边变换。我改变了主意,让我的球员沿对角线移动。它确实有效,但我不知道如何让播放器在到达屏幕末端时停止。我不希望它在另一边转变,而是停下来。到目前为止,我所有的结果要么是边缘出现一些小故障,要么根本没有停止。我已经提供了我的 PlayerController 脚本。现在我的球员沿对角线移动,他将在屏幕边缘后继续。如果有人可以帮助我,我将不胜感激。我从没想过我会处理对角线运动,但我真的很想学习如何做。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class PlayerController : MonoBehaviour {
public float speed = 7;
public float speedy = 7;
public event System.Action OnPlayerDeath;
float screenHalfWidthInWorldUnits;
Rigidbody2D rb;
void Start () {
rb = GetComponent<Rigidbody2D>();
float halfPlayerWidth = transform.localScale.x / 2f;
screenHalfWidthInWorldUnits = Camera.main.aspect * Camera.main.orthographicSize;
}
void Update()
{
float inputX = Input.GetAxisRaw("Horizontal");
float velocity = inputX * speed;
transform.Translate(Vector2.right * velocity * Time.deltaTime);
}
public void MoveRight()
{
rb.velocity = new Vector2(speed, speedy);
}
public void MoveLeft()
{
rb.velocity = new Vector2(-speed, -speedy);
}
public void Stop()
{
rb.velocity = Vector2.zero;
}
void OnTriggerEnter2D(Collider2D triggerCollider)
{
if (triggerCollider.tag =="Box")
{
if (OnPlayerDeath != null)
{
OnPlayerDeath();
}
Destroy(gameObject);
}
}
}
您可以检查玩家是否在您定义的地图边界处。
如果你分别检查 x 轴和 y 轴,你可以将他的 x 轴或 y 轴锁定到边界而不是更远。
这是我之前制作的脚本示例。
如果我理解正确的话,你希望能够沿对角线移动。在我下面的示例脚本中,您可以直线移动也可以沿对角线移动,您也可以在边缘之间弯曲或在边缘停止,就像您所说的那样。
这个脚本可能比您需要的要高级一些,所以如果您对它有任何困惑,请告诉我。
请注意,如果您将布尔值 _ShouldWarp 设置为 false,他将在边界处停止,否则他将在地图的边缘到边缘扭曲。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Player : MonoBehaviour
{
public float _Speed = 5f;
public WorldBounds _WorldBounds;
public bool _ShouldWarp; //If _ShouldWarp is false, will block players movement instead.
void Update()
{
Move();
WarpIfAtBoundary();
}
void Move()
{
float horizontal = Input.GetAxisRaw("Horizontal");
float vertical = Input.GetAxisRaw("Vertical");
transform.Translate(Vector3.right * Time.deltaTime * _Speed * horizontal);
transform.Translate(Vector3.up * Time.deltaTime * _Speed * vertical);
}
void WarpIfAtBoundary()
{
//X Axis
//If player is at positive X boundary
if (transform.position.x > (_WorldBounds.xPlus + _WorldBounds.xBuffer))
{
if (_ShouldWarp) //Teleport/warp player is set to enabled
{
transform.position = new Vector3(_WorldBounds.xMinus, transform.position.y, transform.position.z);
}
else //Otherwise keep player in border position
{
transform.position = new Vector3(_WorldBounds.xPlus + _WorldBounds.xBuffer, transform.position.y, transform.position.z);
}
}
//Else if player is at negative X boundary
else if (transform.position.x < (_WorldBounds.xMinus - _WorldBounds.xBuffer))
{
if (_ShouldWarp)//Teleport/warp player is set to enabled
{
transform.position = new Vector3(_WorldBounds.xPlus, transform.position.y, transform.position.z);
}
else //Otherwise keep player in border position
{
transform.position = new Vector3(_WorldBounds.xMinus - _WorldBounds.xBuffer, transform.position.y, transform.position.z);
}
}
//Y Axis
//If player is at positive Y boundary
if (transform.position.y > (_WorldBounds.yPlus + _WorldBounds.yBuffer))
{
if (_ShouldWarp)//Teleport/warp player is set to enabled
{
transform.position = new Vector3(transform.position.x, _WorldBounds.yMinus, transform.position.z);
}
else //Otherwise keep player in border position
{
transform.position = new Vector3(transform.position.x, _WorldBounds.yPlus + _WorldBounds.yBuffer, transform.position.z);
}
}
//Else if player is at negative Y boundary
else if (transform.position.y < (_WorldBounds.yMinus - _WorldBounds.yBuffer))
{
if (_ShouldWarp)//Teleport/warp player is set to enabled
{
transform.position = new Vector3(transform.position.x, _WorldBounds.yPlus, transform.position.z);
}
else //Otherwise keep player in border position
{
transform.position = new Vector3(transform.position.x, _WorldBounds.yMinus - _WorldBounds.yBuffer, transform.position.z);
}
}
}
}
//Set as serializable so it displays correctly in Unity's inspector window.
[System.Serializable]
public class WorldBounds
{
[Header("Bounds")]
public float xMinus = -9.4f;
public float xPlus = 9.4f;
public float yMinus = -9.4f;
public float yPlus = 9.4f;
[Header("BufferZone")]
public float xBuffer = 1f;
public float yBuffer = 1f;
}
编辑:
With your additions will I be able to assign the movement to my two buttons. One is up and right and the other is down and left.
void Move()
{
float horizontal = Input.GetAxisRaw("Horizontal");
transform.Translate(Vector3.right * Time.deltaTime * _Speed * horizontal);
transform.Translate(Vector3.up * Time.deltaTime * _Speed * horizontal);
}
这应该可以沿对角线向左和向下以及向上和向右移动。
我所做的更改是对 X 和 Y 移动都使用水平输入。
I don't need the warp. Just to step at the defined borders
您可以将 Warp 布尔值设置为 false 或从代码中删除 warp 部分,然后 :-) 应该可以工作。
我有一个测试 2D 游戏,我的玩家从左向右移动,当他到达屏幕的尽头时,它只会在另一边变换。我改变了主意,让我的球员沿对角线移动。它确实有效,但我不知道如何让播放器在到达屏幕末端时停止。我不希望它在另一边转变,而是停下来。到目前为止,我所有的结果要么是边缘出现一些小故障,要么根本没有停止。我已经提供了我的 PlayerController 脚本。现在我的球员沿对角线移动,他将在屏幕边缘后继续。如果有人可以帮助我,我将不胜感激。我从没想过我会处理对角线运动,但我真的很想学习如何做。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class PlayerController : MonoBehaviour {
public float speed = 7;
public float speedy = 7;
public event System.Action OnPlayerDeath;
float screenHalfWidthInWorldUnits;
Rigidbody2D rb;
void Start () {
rb = GetComponent<Rigidbody2D>();
float halfPlayerWidth = transform.localScale.x / 2f;
screenHalfWidthInWorldUnits = Camera.main.aspect * Camera.main.orthographicSize;
}
void Update()
{
float inputX = Input.GetAxisRaw("Horizontal");
float velocity = inputX * speed;
transform.Translate(Vector2.right * velocity * Time.deltaTime);
}
public void MoveRight()
{
rb.velocity = new Vector2(speed, speedy);
}
public void MoveLeft()
{
rb.velocity = new Vector2(-speed, -speedy);
}
public void Stop()
{
rb.velocity = Vector2.zero;
}
void OnTriggerEnter2D(Collider2D triggerCollider)
{
if (triggerCollider.tag =="Box")
{
if (OnPlayerDeath != null)
{
OnPlayerDeath();
}
Destroy(gameObject);
}
}
}
您可以检查玩家是否在您定义的地图边界处。
如果你分别检查 x 轴和 y 轴,你可以将他的 x 轴或 y 轴锁定到边界而不是更远。
这是我之前制作的脚本示例。
如果我理解正确的话,你希望能够沿对角线移动。在我下面的示例脚本中,您可以直线移动也可以沿对角线移动,您也可以在边缘之间弯曲或在边缘停止,就像您所说的那样。
这个脚本可能比您需要的要高级一些,所以如果您对它有任何困惑,请告诉我。
请注意,如果您将布尔值 _ShouldWarp 设置为 false,他将在边界处停止,否则他将在地图的边缘到边缘扭曲。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Player : MonoBehaviour
{
public float _Speed = 5f;
public WorldBounds _WorldBounds;
public bool _ShouldWarp; //If _ShouldWarp is false, will block players movement instead.
void Update()
{
Move();
WarpIfAtBoundary();
}
void Move()
{
float horizontal = Input.GetAxisRaw("Horizontal");
float vertical = Input.GetAxisRaw("Vertical");
transform.Translate(Vector3.right * Time.deltaTime * _Speed * horizontal);
transform.Translate(Vector3.up * Time.deltaTime * _Speed * vertical);
}
void WarpIfAtBoundary()
{
//X Axis
//If player is at positive X boundary
if (transform.position.x > (_WorldBounds.xPlus + _WorldBounds.xBuffer))
{
if (_ShouldWarp) //Teleport/warp player is set to enabled
{
transform.position = new Vector3(_WorldBounds.xMinus, transform.position.y, transform.position.z);
}
else //Otherwise keep player in border position
{
transform.position = new Vector3(_WorldBounds.xPlus + _WorldBounds.xBuffer, transform.position.y, transform.position.z);
}
}
//Else if player is at negative X boundary
else if (transform.position.x < (_WorldBounds.xMinus - _WorldBounds.xBuffer))
{
if (_ShouldWarp)//Teleport/warp player is set to enabled
{
transform.position = new Vector3(_WorldBounds.xPlus, transform.position.y, transform.position.z);
}
else //Otherwise keep player in border position
{
transform.position = new Vector3(_WorldBounds.xMinus - _WorldBounds.xBuffer, transform.position.y, transform.position.z);
}
}
//Y Axis
//If player is at positive Y boundary
if (transform.position.y > (_WorldBounds.yPlus + _WorldBounds.yBuffer))
{
if (_ShouldWarp)//Teleport/warp player is set to enabled
{
transform.position = new Vector3(transform.position.x, _WorldBounds.yMinus, transform.position.z);
}
else //Otherwise keep player in border position
{
transform.position = new Vector3(transform.position.x, _WorldBounds.yPlus + _WorldBounds.yBuffer, transform.position.z);
}
}
//Else if player is at negative Y boundary
else if (transform.position.y < (_WorldBounds.yMinus - _WorldBounds.yBuffer))
{
if (_ShouldWarp)//Teleport/warp player is set to enabled
{
transform.position = new Vector3(transform.position.x, _WorldBounds.yPlus, transform.position.z);
}
else //Otherwise keep player in border position
{
transform.position = new Vector3(transform.position.x, _WorldBounds.yMinus - _WorldBounds.yBuffer, transform.position.z);
}
}
}
}
//Set as serializable so it displays correctly in Unity's inspector window.
[System.Serializable]
public class WorldBounds
{
[Header("Bounds")]
public float xMinus = -9.4f;
public float xPlus = 9.4f;
public float yMinus = -9.4f;
public float yPlus = 9.4f;
[Header("BufferZone")]
public float xBuffer = 1f;
public float yBuffer = 1f;
}
编辑:
With your additions will I be able to assign the movement to my two buttons. One is up and right and the other is down and left.
void Move()
{
float horizontal = Input.GetAxisRaw("Horizontal");
transform.Translate(Vector3.right * Time.deltaTime * _Speed * horizontal);
transform.Translate(Vector3.up * Time.deltaTime * _Speed * horizontal);
}
这应该可以沿对角线向左和向下以及向上和向右移动。
我所做的更改是对 X 和 Y 移动都使用水平输入。
I don't need the warp. Just to step at the defined borders
您可以将 Warp 布尔值设置为 false 或从代码中删除 warp 部分,然后 :-) 应该可以工作。