统一 2d

问题描述 投票:0回答:1

我正在为一款游戏制作角色移动控制器,玩家可以通过按空格键转换为另一个游戏对象。我已经能够给 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);
        }
    }
}
c# unity3d 2d gameobject
1个回答
0
投票

处理两个组件中的空格键是没有意义的!我怀疑你基本上是在切换然后立即切换回来,因为另一个组件在另一个方向上做同样的事情......我宁愿将它设置在一个中央控制器上,它是一个保持活动状态的对象,它控制另外两个对象 .. 还有你的两个运动输入不匹配,这可能会导致非常烦人的用户体验;)

所以我宁愿有类似的东西。 (附在你的两个受控对象上)

// 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;
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.