我目前正在尝试制作 Unity3d(在这种情况下为 2D)平台游戏技术演示。在进行演示时,我遇到了一些障碍,因为我希望我的 Player 对象能够上坡,但是如果我在 Player 对象在地面上时应用重力,它将无法上坡,即使它可以让他们失望。我的解决方案是在 PLayer 对象接触地面时关闭重力,并在没有时将其重新打开。我通过使用功能void OnCollisionEnter2D(Collision2D collision)
关闭重力并void OnCollisionExit2D(Collision2D collision)
重新打开它来做到这一点。
这不起作用,所以我玩了一下,并想到了给地面和玩家对象“触发框”的想法,这些对象是看不见的子立方体对象,有一个标记为触发器的碰撞器。所以现在我正在使用这个功能void OnTriggerEnter2D(Collider2D collision)
来关闭重力,然后void OnTriggerExit2D(Collider2D collision)
重新打开它。但这也行不通。下面是我的代码,首先是 Player 对象的主脚本,然后是 Player 对象的“TriggerBox”,然后是显示我的对象如何在 Unity 中设置的图像。
结果:Player 类当前没有与地面发生碰撞,而是从地面坠落到无穷远处。
我想要的是:玩家与地面发生碰撞,玩家的 TriggerBox 与地面的“TriggerBox”发生碰撞并关闭玩家的重力。
笔记:我尝试过给玩家和地面 RigidBody2Ds。玩家与地面发生碰撞并抖动,并不会触发重力关闭,当地面有 RigidBody2D 时,地面会与玩家接触。目前尚不清楚是什么触发的,因为地面正好落在玩家的下方。
using UnityEngine;
using System.Collections;
public class PlayerControls : MonoBehaviour {
CharacterController controller;
private float speed = 0.004f;
private float fallSpeed = 0.01f;
private Vector3 tempPos;
bool onGround = false;
public void setOnGround(bool b){ onGround = b; }
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
tempPos = Vector3.zero;
if(Input.GetKey(KeyCode.W)) tempPos.y -= speed;
if(Input.GetKey(KeyCode.S)) tempPos.y += speed;
if(Input.GetKey(KeyCode.A)) tempPos.x -= speed;
if(Input.GetKey(KeyCode.D)) tempPos.x += speed;
RaycastHit2D[] hits = Physics2D.RaycastAll(new Vector2(transform.position.x,transform.position.y), new Vector2(0, -1), 0.2f);
float fallDist = -fallSpeed;
if(hits.Length > 1){
Vector3 temp3Norm = new Vector3(hits[1].normal.x, hits[1].normal.y, 0);
Vector3 temp3Pos = new Vector3(tempPos.x, tempPos.y, 0);
temp3Pos = Quaternion.FromToRotation(transform.up, temp3Norm) * temp3Pos;
tempPos = new Vector2(temp3Pos.x, temp3Pos.y);
}
if(!onGround) tempPos.y = fallDist;
transform.Translate(tempPos);
}
}
接下来是 TriggerBox:
using UnityEngine;
using System.Collections;
public class PlayerTriggerBox : MonoBehaviour {
public PlayerControls playerControls;
// Use this for initialization
void Start () {
//playerControls = gameOGetComponent<PlayerControls>();
if(playerControls == null) Debug.Log("playerControls IS NULL IN PlayerTriggerBox!");
}
// Update is called once per frame
void Update () {
}
void OnTriggerEnter2D(Collider2D other) {
playerControls.setOnGround(true);
}
void OnTriggerExit2D(Collision2D collision){
playerControls.setOnGround(false);
}
}
-至于我的设置图像-
玩家的设置: 玩家的 TriggerBox 设置: 地面的设置: 地面的 TriggerBox 设置:
感谢您抽出宝贵的时间阅读本文,并希望对您有所帮助。