我正在为一款游戏制作角色移动控制器,玩家可以通过按空格键转换为另一个游戏对象。我已经能够给 2 个游戏对象相同的位置,但我不确定如何给它们相同的 x 和 y 速度。
我试过引用相反游戏对象的刚体,然后将其设置为活动游戏对象的当前速度,但这不起作用。速度不传递过来。我正在切换的两个游戏对象是一个玩家和一个球。
这是播放器的代码(默认)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerScript : MonoBehaviour
{
public GameObject ball1;
public GameObject player1;
public Rigidbody2D ballRB2D;
public Rigidbody2D rb2d;
public float speed;
public float jump;
float moveVelocity;
public bool grounded = true;
void OnTriggerEnter2D()
{
grounded = true;
}
private void OnTriggerStay()
{
grounded = true;
}
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
ball1.transform.position = new Vector2(transform.position.x, transform.position.y);
ballRB2D.velocity = new Vector2(rb2d.velocity.x, rb2d.velocity.y);
ball1.SetActive(true);
player1.SetActive(false);
}
if (Input.GetKeyDown(KeyCode.W) || Input.GetKeyDown(KeyCode.UpArrow))
{
if (grounded)
{
rb2d.velocity = new Vector2(rb2d.velocity.x, jump);
grounded = false;
}
}
moveVelocity = 0;
//Left Right Movement
if (Input.GetKey(KeyCode.LeftArrow) || Input.GetKey(KeyCode.A))
{
moveVelocity = -speed;
}
if (Input.GetKey(KeyCode.RightArrow) || Input.GetKey(KeyCode.D))
{
moveVelocity = speed;
}
rb2d.velocity = new Vector2(moveVelocity, rb2d.velocity.y);
}
}
这是球的代码(其他游戏对象)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class BallScript : MonoBehaviour
{
public Rigidbody2D rb2d;
public float moveSpeed = 5;
public GameObject player;
public GameObject ball;
public Rigidbody2D playerRB2D;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
player.transform.position = new Vector2(transform.position.x, transform.position.y);
playerRB2D.velocity = new Vector2(rb2d.velocity.x, rb2d.velocity.y);
player.SetActive(true);
ball.SetActive(false);
}
if (Input.GetKey(KeyCode.LeftArrow))
{
rb2d.velocity = new Vector2(-moveSpeed , rb2d.velocity.y);
}
else if (Input.GetKey(KeyCode.RightArrow))
{
rb2d.velocity = new Vector2(moveSpeed, rb2d.velocity.y);
}
}
}
处理两个组件中的空格键是没有意义的!我怀疑你基本上是在切换然后立即切换回来,因为另一个组件在另一个方向上做同样的事情......我宁愿将它设置在一个中央控制器上,它是一个保持活动状态的对象,它控制另外两个对象 .. 还有你的两个运动输入不匹配,这可能会导致非常烦人的用户体验;)
所以我宁愿有类似的东西。 (附在你的两个受控对象上)
// Attached to each of your player/ball objects
public class Character : MonoBehaviour
{
// reference this objects rigidbody via Inspector
[SerializeField] private Rigidbody2D _rigidbody;
// public read-only access (encapsulation)
public Rigidbody2D Rigidbody => _rigidbody;
// Event others can attach listeners to
public event Action onGround;
private void Awake()
{
// Get on runtime as fallback
OnValidate();
}
private void Reset()
{
OnValidate();
}
private void OnValidate()
{
if(!_rigidbody) _rigidbody = GetComponent<Rigidody2D>();
}
private void OnTriggerEnter2D()
{
// invoke event if someone is listening
onGround?.Invoke();
}
private void OnTriggerStay()
{
onGround?.Invoke();
}
}
然后(附加到中央控制器对象,而不是特定的受控对象)
public class MovementAndSwitchController : MonoBehaviour
{
// reference the two (all) available characters via Inspector
[SerializeField] private Character[] _availableCharacters;
// index of the current active character
private int _currentCharacter;
private bool _grounded;
private void Start()
{
// Initially actuvate and listen to first character in array
_availableCharacters[0].gameObject.SetActive(true);
// just in case remove the listener first -> ensures it is always listening only once
_availableCharacters[0].onGround -= HandleGrounded;
_availableCharacters[0].onGround += HandleGrounded;
// deactivate all other characters
for(var i = 1; i < _availableCharacters.Length; i++)
{
_availableCharacters[i].gameObjet.SetActive(false);
}
}
private void Update()
{
var current = _availableCharacters[_currentCharacter];
// Handle character switch
if (Input.GetKeyDown(KeyCode.Space))
{
// increase index with wrap around at the end
_currentCharacter = (_currentCharacter + 1) % _availableCharacters.Length;
var next = _availableCharacters[_currentCharacter];
// copy over position and velocity
// note that Vector2 is a struct an therefore you don't need to use "new" here
next.Rigidbody.position = current.Rigidbody.position;
next.Rigidbody.velocity = current.Rigidbody.velocity;
// switch the active state
current.gameObject.SetActive(false);
next.gameObject.SetActive(true);
// stop listening to the previous character
current.onGround -= HandleGrounded;
// start listening to the new character
next.onGround -= HandleGrounded;
next.onGround += HandleGrounded;
// and finally switch them also in the local variable to be further handled below
current = next;
}
// Handle movement input
var velocity = current.Rigidbody.velocity;
if (Input.GetKey(KeyCode.LeftArrow) || Input.GetKey(KeyCode.A))
{
velocity.x = -speed;
}
else if (Input.GetKey(KeyCode.RightArrow) || Input.GetKey(KeyCode.D))
{
velocity.x = speed;
}
if (_grounded && (Input.GetKeyDown(KeyCode.W) || Input.GetKeyDown(KeyCode.UpArrow)))
{
velocity.y = jump;
_grounded = false;
}
current.Rigidbody.velocity = velocity;
}
private void HandleGrounded()
{
_grounded = true;
}
}