使用Android加速度计y轴穿过地形 - Unity3D

时间:2014-07-19 17:43:00

标签: android unity3d accelerometer

效果更好,谢谢。但是,它仍然不能很好地工作。虽然我没有完全穿过地形,但FP控制器似乎悬停在地形下方。添加+10有帮助,但还有另一个奇怪的问题: 我将相机设置为FP控制器的子级,为0,0,0。当游戏开始运行时,控制器窗口变换中的Y值以负数稳定下降,而摄像机Y值在正方向上稳定上升。 Y值是镜像的。对于发生了什么的任何想法?

void Update () {
    moveX = Input.acceleration.x * 1;
    moveY = Input.acceleration.y * 1;
    moveZ = (1+ (Input.acceleration.z)); 
    transform.Translate (0, 0, 0); //transform.translate Moves the transform in the direction and distance of translation

    temp = transform.position;     //temp = the position of the transform in world space. World Space: the absolute XYZ coordinates of all objects
    temp.y = terrainY;             //y component of Vector3 (float)
    transform.position = temp;     //put the position of the transform in world space back into temp
    terrainY = Terrain.activeTerrain.SampleHeight(temp); //Sample.height Samples the height at the given position defined in world space

    temp2 = transform.position.y; //this shows transform.position.y axis is the same as terrainY, but not the same value as shown in the inspector

        if (moveZ >= 0.055 && moveZ >= -0.1) { 
        zeroZFlag = 1;          
        if(moveZ >= 0.041){
            moveZ = moveZ*10;     //multiply by 10 to make it faster when going forward
                if (moveY >= 0) {        

                transform.Translate (moveX,terrainY + 10,moveZ); 
                //transform.translate needs to be three floats. So the middle one needs to be the y value of the top of the terrain
                    }
                    if (moveY < 0){
                transform.Translate (moveX,terrainY,-moveZ);
                    }
        }

我已根据建议添加到我的代码中,但仍然无法让第一人称控制器保持与地形相同的y值。在下面的代码迭代中,第一个人的y值完全离开了这个世界并永远地上升。 我的代码使用     `transform.Translate(moveX,terrainY,moveZ); 移动FP控制器,其中moveX和moveY是加速度值,terrainY理论上应该是Y轴的实际值,如变换框所示。 我认为第一个问题是我将加速度值(X,Z)与Y的地形变换混合,因此值的含义不同。 使用此代码,BTW X和Z轴与加速度计一起移动得非常好,但如有必要,我会更改所有内容!

我不确定translate.transform的浮点值操作是什么。手册说明它在space.world中返回,但它是按单位数还是位置移动?

这是我的新代码,并提前感谢您的帮助:

public float terrainY;

// y axis falls through terrain
// travels through walls even though collider is set

void LateUpdate (){
    //terrainY = Terrain.activeTerrain.SampleHeight (transform.position);
    }
void Update () {
    moveX = Input.acceleration.x * 1;
    moveY = Input.acceleration.y * 1;
    moveZ = (1+ (Input.acceleration.z)); 
    transform.Translate (0, 0, 0);
    terrainY = Terrain.activeTerrain.SampleHeight (transform.position);
    if (moveZ >= 0.055 && moveZ >= -0.1) { 
        zeroZFlag = 1;          
        if(moveZ >= 0.041){
            moveZ = moveZ*10; //multiply by 10 to make it faster when going forward
                    if (moveY >= 0) {
                transform.Translate (moveX,terrainY,moveZ); 
                //transform.translate needs to be three floats. so the middle one needs to be the y value of the top of the terrain
                    }
                    if (moveY < 0){
                transform.Translate (moveX,terrainY,-moveZ);
                    }

我的代码使我在Unity 3D中经历并且在我的terrrain下,因为y轴始终为零。在这个世界中,x轴是左/右,z是深度。 Y轴向上/向下,沿着山脉,丘陵,山谷在地形中追逐。然而,它只是通过,在0高度。 有谁知道y轴上的变量/类应该是什么而不是我有的“0”?提前谢谢!

public class Movement2 : MonoBehaviour {
public float moveX = Input.acceleration.x;
public float moveY = Input.acceleration.y;
public float moveZ = Input.acceleration.z;
public float Speed = 20.0f;
public int zeroZFlag;

void Update () {
    moveX = Input.acceleration.x * 1;
    moveY = Input.acceleration.y * 1;;
    //moveZ = Mathf.Abs(1+ (Input.acceleration.z) * 20); 
    moveZ = (1+ (Input.acceleration.z)); 
    transform.Translate (0, 0, 0);

    if (moveZ >= 0.055 && moveZ >= -0.1) { zeroZFlag = 1;                       
                    if (moveY >= 0) {
            transform.Translate (moveX,0,moveZ);
                    }
                    if (moveY < 0){
            transform.Translate (moveX,0,-moveZ);
                    }
     else {
     zeroZFlag = 0;  
     }
    }

2 个答案:

答案 0 :(得分:0)

尝试使用Terrain.SampleHeight(),它会返回具有给定X和Z坐标的地形高度。每隔Update()将其Y位置更新为地形高度。

参考:http://docs.unity3d.com/ScriptReference/Terrain.SampleHeight.html

编辑1:
你的FP控制器总是永远上升的原因是因为你继续将一个Y值进行翻译。

transform.Translate(moveX, terrainY, moveZ)
// this way you keep adding terrainY value to the Y position
// thus it always goes up and will never end

虽然您需要FP控制器与地形始终保持相同的Y位置。您应该直接修改Y的位置。

Vector3 temp = transform.position;
temp.y = terrainY;
transform.position = temp;

编辑2:
我尽力帮助您查看代码:

void Update () {
    moveX = Input.acceleration.x * 1;
    moveY = Input.acceleration.y * 1;
    moveZ = (1+ (Input.acceleration.z)); 
    transform.Translate (0, 0, 0); // why do you need this? this basically does nothing

    // you should get terrain height first to be used as temp.y below
    terrainY = Terrain.activeTerrain.SampleHeight(transform.position);
    temp = transform.position;
    temp.y = terrainY + 10; // you said +10 helped, so I put it here
    transform.position = temp;        

    if (moveZ >= 0.055 && moveZ >= -0.1) { 
        zeroZFlag = 1;          
        if(moveZ >= 0.041){
            moveZ = moveZ*10;
            if (moveY >= 0) {        
             // here I think you shouldn't move the Y anywhere,
             // because you've updated position of Y in every update frame   
             // so you only need to move X and Z due to device tilt   
                transform.Translate (moveX,0,moveZ); 
            }
            if (moveY < 0){
                transform.Translate (moveX,0,-moveZ);
            }
        }

答案 1 :(得分:0)

这也有效:

  using UnityEngine;
  using System.Collections;
  [RequireComponent(typeof(CharacterController))]
  public class Movement6 : MonoBehaviour {
  public float speed = 30.0f;

  public float moveX = Input.acceleration.x;
  public float moveY = Input.acceleration.y;
  public float moveZ = Input.acceleration.z;
    void Update() {
    moveX = Input.acceleration.x * 1;
    moveY = Input.acceleration.y * 1;
    moveZ = (1+ (Input.acceleration.z)); 

    CharacterController controller = GetComponent<CharacterController>();
    Vector3 forward = transform.TransformDirection(moveX,0,moveZ);
    controller.SimpleMove (forward * speed);
    }
}