我目前正在尝试制作Unity3d(在本例中为2D)平台技术演示。
在演示时,我遇到了一些障碍,因为我希望我的Player对象能够上坡,但如果我在Player对象在地面时施加重力,它将无法上坡,即使它可以降低它们。我的解决方案是在PLayer物体接触地面时关闭重力,并在它没有时将其重新打开。我通过使用函数void OnCollisionEnter2D(Collision2D collision)
来关闭重力来完成此操作,并void OnCollisionExit2D(Collision2D collision)
将其重新打开。
这不起作用,所以我玩了一下,并想到了让地面和玩家对象" Trigger Boxes"这些是看不见的子Cube对象,它们将Collider标记为Trigger。所以现在我使用函数void OnTriggerEnter2D(Collider2D collision)
来关闭重力,并void OnTriggerExit2D(Collider2D collision)
将其重新打开。但这也行不通。下面是我的代码,首先是Player对象的主脚本,然后是Player对象" TriggerBox"之后将显示图像以显示我在Unity中如何设置对象。
结果:Player类当前不会与地面发生碰撞,并通过它落到无限远。
我想要的:玩家与地面发生碰撞,玩家的TriggerBox与地面碰撞" TriggerBox"并关闭玩家的引力。
注意:我已经尝试过给予玩家,并将RigidBody2D打开。玩家与地面相撞并变得紧张,并且不会触发重力关闭,当地面具有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设置:
感谢您抽出时间阅读本文,并希望能为您提供帮助。