我正在开发一个平台游戏,其中一个球应该能够左右移动并跳跃。我可以使角色成功跳跃或移动,但是当我尝试检查它是否在地面上时,通过使用触发器对撞机2D创建一个作为该角色的子元素的元素,并使用一个应该玩家接触地面时为true,否则为false,只是没有激活。
以下是主要运动脚本的代码:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Grounded : MonoBehaviour
{
GameObject Player;
// Start is called before the first frame update
void Start()
{
Player = gameObject.transform.parent.gameObject;
}
// Update is called once per frame
void Update()
{
}
private void OnTriggerEnter2D(Collider2D collision)
{
if (GetComponent<Collider2D>().tag == "Ground")
{
Player.GetComponent<Move2D>().isGrounded = true;
}
}
private void OnTriggerExit2D(Collider2D collision)
{
if (GetComponent<Collider2D>().tag == "Ground")
{
Player.GetComponent<Move2D>().isGrounded = true;
}
}
}
这是 Grounded 脚本:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Move2D : MonoBehaviour
{
public float moveSpeed = 5f;
public bool isGrounded = false;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
Jump();
Vector3 movement = new Vector3(Input.GetAxis("Horizontal"), 0f, 0f);
transform.position += movement * Time.deltaTime * moveSpeed;
}
void Jump()
{
if (Input.GetButtonDown("Jump") && isGrounded)
{
gameObject.GetComponent<Rigidbody2D>().AddForce(new Vector3(0f, 5f), ForceMode2D.Impulse);
}
}
}
任何帮助或信息都非常感谢。
答案 0 :(得分:1)
您能检查一下球和地面是否都具有刚体?触发触发器是必需的。
*注意:仅当其中一个碰撞器还附有刚体时才发送触发事件。 *
您还可以更改代码
private void OnTriggerEnter2D(Collider2D collision)
{
if (GetComponent<Collider2D>().tag == "Ground")
{
Player.GetComponent<Move2D>().isGrounded = true;
}
}
private void OnTriggerEnter2D(Collider2D collision)
{
if (collision.tag == "Ground")
{
Player.GetComponent<Move2D>().isGrounded = true;
}
}
我也建议您使用“图层”而不是标签
答案 1 :(得分:1)
在
GetComponent<Collider2D>().tag == "Ground"
您正在检查此GameObject(玩家的孩子)对撞机本身的tag
!
您可能宁愿检查与之碰撞的事物的tag
。
也要避免重复GetComponent
调用..而不是只执行一次。
(感谢@Jichael)您也应该使用CompareTag
而不是tag == "XY"
。它是more efficient,实际上还检查给定的比较字符串是否作为标记存在。如果没有,则在使用==
时会抛出错误,只是返回false,这使得很难找到evtl。错字。
// Would be better even to already reference this via Inspector
[SerializeField] private Move2D Player;
private void Awake()
{
if(!Player) Player = GetComponentInParent<Move2D>();
}
private void OnTriggerEnter2D(Collider2D collision)
{
if (collision.CompareTag("Ground"))
{
Player.isGrounded = true;
}
}
private void OnTriggerExit2D(Collider2D collision)
{
if (collision.CompareTag("Ground"))
{
Player.isGrounded = true;
}
}
Move2D
[SerializeField] private Rigidbody2D rigidbody;
private void Awake()
{
if(!rigidbody) rigidbody = GetComppnent<Rigidbody2D>();
}
void Jump()
{
// This is very small but it is slightly cheaper to check the
// isGrounded value so this order is minimal faster if isGrounded is false
if (isGrounded && Input.GetButtonDown("Jump"))
{
rigidbody.AddForce(new Vector3(0f, 5f), ForceMode2D.Impulse);
}
}
还请注意:每当涉及到刚体时,您都不应通过Transform
组件控制位置,而应使用Rigidbody2D.MovePosition
来保持物理状态不变!
但这必须在FixedUpdate
中完成,这样您的代码才能变成类似
private Vector3 movement;
void Update()
{
Jump();
movement = new Vector3(Input.GetAxis("Horizontal"), 0f, 0f);
}
private void FixedUpdate ()
{
rigidbody.MovePosition(rigidbody.position += movement * Time.deltaTime * moveSpeed);
}
void Jump()
{
if (Input.GetButtonDown("Jump") && isGrounded)
{
rigidbody.AddForce(new Vector3(0f, 5f), ForceMode2D.Impulse);
}
}
这两个对象是否都需要刚体或仅玩家依赖地面对象(afaik):