我现在正在玩游戏(第一款3D风格的游戏),我的角色碰撞有问题。我有一个Player对象,它有另一个对象作为真正的可移动字符(现在我只有一个)。我的刚性和箱式对撞机太贴在我的角色上了。我已经制作了一个级别(使用手动放置的平台),我想避免我的平台掉落的特性,而用户控制它。我曾尝试在平台的一侧放置一个立方体,并在其上安装了盒子对撞机,但由于某些原因,角色没有检测到碰撞。我希望我的角色被对撞机" cube"停止,但它不会发生。
我使用此脚本移动我的对象(附加到我的角色Player对象):
public class Bounce : MonoBehaviour {
float lerpTime;
float currentLerpTime;
float perc = 1;
Vector3 startPos;
Vector3 endPos;
bool firstInput;
public bool justJump;
public GameObject player;
// Update is called once per frame
void Update () {
if (Input.GetButtonDown("up") || Input.GetButtonDown("down") || Input.GetButtonDown("left") || Input.GetButtonDown("right")) {
if (perc == 1) {
lerpTime = 1;
currentLerpTime = 0;
firstInput = true;
justJump = true;
}
}
startPos = gameObject.transform.position;
if (Input.GetButtonDown("up") && gameObject.transform.position == endPos) {
endPos = transform.position + player.transform.rotation * (new Vector3(0, 0, 1f));
}
if (Input.GetButtonDown("down") && gameObject.transform.position == endPos) {
endPos = transform.position + player.transform.rotation * (new Vector3(0, 0, -1f));
}
if (firstInput == true) {
currentLerpTime += Time.deltaTime * 5;
perc = currentLerpTime / lerpTime;
gameObject.transform.position = Vector3.Lerp(startPos, endPos, perc);
if (perc > 0.8f) {
perc = 1;
}
if (Mathf.Round(perc) == 1) {
justJump = false;
}
}
}
void OnCollisionEnter(Collision collision) {
Debug.Log("!!!!!!!");
}
}
我在角色本身使用这个脚本:(旋转和动画)
代码(csharp):
public class AnimationController : MonoBehaviour {
Animator anim;
public GameObject thePlayer;
// Use this for initialization
void Start () {
anim = gameObject.GetComponent<Animator>();
}
// Update is called once per frame
void Update () {
Bounce bounceScript = thePlayer.GetComponent<Bounce>();
if (bounceScript.justJump == true) {
anim.SetBool("Jump", true);
}
else {
anim.SetBool("Jump", false);
}
if (Input.GetButtonDown("right")) {
//transform.rotation *= Quaternion.Euler(0,30,0);
transform.RotateAround(transform.position, Vector3.up, 90);
}
if (Input.GetButtonDown("left")) {
transform.Rotate (0, -90, 0, 0);
}
}
}
只有当立方体不是运动时它才会发生碰撞,但它并不能阻止我的玩家因某种原因通过立方体。
我已经阅读了一些有关此类问题的网站,但没有任何帮助。
如果你能给我任何代码改进,那就太好了。)
EDIT1:
很抱歉,为了回答这么晚,过去几天我的游戏无法做任何事情。今天我尝试用光线投射做一些事情,你可以看到我的代码,我第一次尝试只是在更新方法中:
void Update () {
if (Input.GetButtonDown("up") || Input.GetButtonDown("down") || Input.GetButtonDown("left") || Input.GetButtonDown("right")) {
if (perc == 1) {
lerpTime = 1;
currentLerpTime = 0;
firstInput = true;
justJump = true;
}
}
startPos = gameObject.transform.position;
/* if (Input.GetButtonDown("right") && gameObject.transform.position == endPos) {
//endPos = new Vector3(transform.position.x + 0.5f, transform.position.y, transform.position.z);
}
if (Input.GetButtonDown("left") && gameObject.transform.position == endPos) {
endPos = new Vector3(transform.position.x - 0.5f, transform.position.y, transform.position.z);
}*/
Vector3 fwd = player.transform.TransformDirection(Vector3.forward);
RaycastHit objectHit;
if (Physics.Raycast(player.transform.position, fwd, out objectHit, 2)) {
if (objectHit.collider.tag == "Wall") {
Debug.Log("WALL RAYCAST HIT!");
}
}
if (Input.GetButtonDown("up") && gameObject.transform.position == endPos) {
endPos = transform.position + player.transform.rotation * (new Vector3(0, 0, 1f));
}
if (Input.GetButtonDown("down") && gameObject.transform.position == endPos) {
//endPos = transform.position + player.transform.rotation * (new Vector3(0, 0, -1f));
}
if (firstInput == true) {
currentLerpTime += Time.deltaTime * 5;
perc = currentLerpTime / lerpTime;
gameObject.transform.position = Vector3.Lerp(startPos, endPos, perc);
if (perc > 0.8f) {
perc = 1;
}
if (Mathf.Round(perc) == 1) {
justJump = false;
}
}
}
有了这个,我可以一次2-3次调试日志WALL RAYCAST HIT,但只有一次。当我移动角色时,由于某种原因它不会再次出现(我认为应该因为在每一帧中调用更新方法)。
虽然当我将它放在Input.GetButtonDown(&#34; up&#34;)方法中时,它不会记录任何内容:
if (Input.GetButtonDown("up") && gameObject.transform.position == endPos) {
fwd = player.transform.TransformDirection(Vector3.forward);
if (Physics.Raycast(player.transform.position, fwd, out objectHit, 2)) {
if (objectHit.collider.tag == "Wall") {
Debug.Log("WALL RAYCAST HIT!");
}
}
endPos = transform.position + player.transform.rotation * (new Vector3(0, 0, 1f));
}
答案 0 :(得分:0)
当你更新transform.position时,你实际上是&#34;传送&#34;你反对新的立场。即使你顺利地使用像Lerp函数这样的东西,就像你在移动脚本上那样,Unity也知道你将对象传送到新的坐标。
这没错,所有游戏都是这样的。像Lerp这样的功能只是创造了运动的幻觉,所以玩家就像实际从一个点移动到另一个点的角色一样。
正在发生的事情是,尽管路径上有任何对象,但您的脚本仍会告诉角色移动到新位置。碰撞发生,但你的更新功能仍然将角色置于新的位置。
我可以想到两种可能的解决方法:
为Move脚本创建一个 OnCollisionEnter()函数,以某种方式阻止您的移动。通过像 firstInput 那样创建标记,您可以实现此目的。
您可以使用刚体来处理移动和碰撞,而不是更新您的transform.position。这样,每当你需要移动角色时,你需要为角色刚体添加一些速度,而不是直接更新transform.position。
因为你的角色不会以一种恒定的方式移动,而是一次一步地移动#34;方式,我认为第一个解决方案更适合你。
代码将是这样的
void OnCollisionenter(Collision collision)
{
collided = true;
}
并且Move脚本的结尾应更新为
if(!collided)
{
if (firstInput == true) {
currentLerpTime += Time.deltaTime * 5;
perc = currentLerpTime / lerpTime;
transform.position = Vector3.Lerp(startPos, endPos, perc);
if (perc > 0.8f) {
perc = 1;
}
if (Mathf.Round(perc) == 1) {
justJump = false;
}
}
}
else
{
// Remember to reset this when you stop your character
endPos = transform.position;
collided = false;
}
这次我在编写代码之前无法测试代码,因此您可能需要在工作之前进行一些更改。
ps:我认为您不需要 firstInput 变量。一旦设置为true,您再也不会将其设置为false。此外, Input.GetButtonDown()函数仅在按下按钮的第一帧时返回true,这就是我在您创建 firstInput 时的预期。
ps2:我的解决方案为您的班级添加了碰撞布尔属性,因此不要忘记添加一行private bool collided;
与您的其他类属性。另外,请阅读关于我在其他问题上推荐您的状态机模式的章节。创建这种控制属性suach作为碰撞布尔值不是一个好习惯,如果你已经实现了状态机,这可以避免。
答案 1 :(得分:0)
嘿,我有一个类似的问题,我使用Mixamo.com的动画模型,我注意到,由于一些奇怪的原因,角色没有碰撞边界,尽管有对撞机,由于某种原因,它直到我添加后才起作用一个 CharacterController 到我的模型而不是碰撞器只是搜索CharacterController并添加它,就像你将任何脚本或刚体添加到你的游戏对象一样。
希望它有效XD问候