zoukankan      html  css  js  c++  java
  • unity自动校准

    关于unity中校准的问题,在论坛里查过很多资料.最后好友推荐了一篇老外写的博客.关于校准给了一个很好的实现.

    问题是老外用objective-c写的.后来自己翻译成unity中的c#脚本与自己的一点改进.很好的实现了unity平台的校准功能.

    具体博文地址如下:http://www.paradeofrain.com/2010/07/lessons-learned-in-tilt-controls/

    我对该博文做了一下翻译,自己翻译能力有限,刚过六级,大家觉得有翻得不好的地方,欢迎提出来.我改进.

    翻译链接http://www.cnblogs.com/xckk/archive/2012/09/02/2667838.html

    老外的具体实现如下

    - (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration
    {
    /* while not ideal, most of the relevant code is stuffed in this method for clarity. A lot can be computed once
    and saved in instance variables, preferences, etc instead of re-calculating each frame
    */
    
    // hard coding our 'neutral' orientation. By default this is the orientation of
    // having the device tilted slightly towards your face.
    // if you wanted strictly a 'top down' orientation then a (0,0,-1) vector would be put here.
    // to create a new 'neutral' position you can sample the UIAcceleration parameter for a single
    // frame and set that to be the new nx,ny,nz for the remainder of the app (aka calibrating).
    const float nx = -0.63f;
    const float ny = 0;
    const float nz = -0.92f;
    
    // this quaternion represents an orientation (I like to think of it as a 3D vector with 0 rotation in this case)
    // that points straight out from the device's back away from the user's face.
    Quaternion neutral(0,nx, ny, nz);
    // take a straight up vector and rotate it by our 'neutral' orientation
    // to give us a vector that points straight out from the device's screen (at the user's face)
    Quaternion neutralPosition = neutral * Quaternion(0,0,0,1);
    
    /* now with our 'neutral' quaternion setup we:
    1. take the incoming accelerometer data
    2. convert it to a 2D velocity projected onto the plane of the device's screen
    3. and rotate it by 90 degrees (since we are landscape oriented) and feed it to our player's
    velocity directly.
    */
    
    // convert our accel data to a Quaternion
    Quaternion accelQuat(0, acceleration.x, acceleration.y, acceleration.z);
    
    // now rotate our accel data BY the neutral orientation. effectively transforming it
    // into our local space.
    Vec3 accelVector = (accelQuat * neutralPosition).v; // we only want the 3D vector at this point
    
    // now with our accel vector we wish to transform it into our standard (1,1,1) coordinate space
    Vec3 planeXAxis(1,0,0);
    Vec3 planeYAxis(0,1,0);
    Vec3 normal(0,0,1); // the normal of the plane we wish to transform our data into.
    
    //project this movement onto our X/Y plane by removing
    // the accel part that is along our normal
    // note: Vec3 * Vec3 = dot product of the 2 vectors.
    Vec3 projection = accelVector - normal *(accelVector * normal);
    
    // now decompose that projection along our X and Y axis that represents our 2D plane
    Vec2 accel2D(0,0);
    accel2D.x = planeXAxis * projection;
    accel2D.y = planeYAxis * projection;
    
    const float xSensitivity = 2.8f;
    const float ySensitivity = 2.8f; // yay magic numbers!
    const float tiltAmplifier = 8; // w0ot more magic numbers
    
    // now apply it to our player's velocity data.
    // we also rotate the 2D vector by 90 degrees by switching the components and negating one
    // since we are in a landscape orientation.
    vx += (-accel2D.y) * tiltAmplifier * xSensitivity;
    vy -= accel2D.x * tiltAmplifier * ySensitivity; // we do a (-) here because the accel y axis is inverted.
    }

     这是老外写的原始方法,该方法后面有改进.但是我认为这个方法比较容易理解.

    后面是改进的方法,代码更少了,但是理解起来有点困难

    - (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration
    {
    // A much more concise version courtesy of Mikko Mononen http://digestingduck.blogspot.com/
    Vec2 accel2D(0,0);
    Vec3 ax(1, 0, 0);
    Vec3 ay(-.63f, 0,-.92f);
    Vec3 az(Vec3::Cross(ay,ax).normalize());
    ax = Vec3::Cross(az,ay).normalize();
    
    accel2D.x = -Vec3::Dot(Vec3(acceleration.x, acceleration.y, acceleration.z), ax);
    accel2D.y = -Vec3::Dot(Vec3(acceleration.x, acceleration.y, acceleration.z), az);
    
    const float xSensitivity = 2.8f;
    const float ySensitivity = 2.8f; // yay magic numbers!
    const float tiltAmplifier = 8; // w0ot more magic numbers
    
    // since we are in a landscape orientation.
    // now apply it to our player's velocity data.
    // we also rotate the 2D vector by 90 degrees by switching the components and negating one
    vx += -(accel2D.y) * tiltAmplifier * xSensitivity;
    vy += accel2D.x * tiltAmplifier * ySensitivity;
    
    }

    我将两种方法分别翻译成了unity的C#脚本.这里先只贴出第二种方法的,第一种方法的暂时不知道到哪去了.

    public static Vector3 getAccelerator2()
        {
            Vector3 accelerator = Input.acceleration;
            
            Vector3 accel2D = Vector3.zero;
            Vector3 ax = new Vector3(1, 0, 0);
            Vector3 ay = neutralVector3;
            Vector3 az = Vector3.Cross(ay, ax).normalized;
            
            ax = Vector3.Cross(az, ay).normalized;
            
            accel2D.x = -Vector3.Dot(accelerator, ax);
            accel2D.y = -Vector3.Dot(accelerator, az);
            
            float t = accel2D.x;    
            accel2D.x = -accel2D.y;
            accel2D.y = t;
            
            accel2D.y = -accel2D.y;
            
            if(!isRightDirection)
            {
                accel2D.y = -accel2D.y;
                accel2D.x = -accel2D.x;
            }
    
            return accel2D;
        }

    方法中neutralVector3就是你校准平衡位置的加速度值,即Input.acceleration.校准方法如下:

    每次需要校准时,调用下面方法即可:

    注意,当iphone4设备向上抬超过90度时,加速度计的值会反转.因此做了一下判断

    本文做的是landscape left方向.其它的方向可以依此类推

    public static void setNeutralVector()
        {
            neutralVector3 = Input.acceleration;
            if(neutralVector3.z < 0)
            {
                isRightDirection = true;
            }else
            {
                isRightDirection = false;
            }
        }

     希望对校准一直没有好的解决方案的同学有所帮助.欢迎大家提问题,一起学习.

    秀才坤坤出品

  • 相关阅读:
    webpack中如何使用vue
    webpack 4.X 与 Vue 2.X结合
    webpack创建页面的过程
    webpack的css样式文件加载依赖
    webpack-dev-server的执行逻辑
    WebPack命令执行的时候,其内部处理逻辑是什么
    idea for Mac for循环快捷键
    java知识点集锦--基础知识部分
    npm --save-dev --save | -D -S区别
    mysql估算存储数据量
  • 原文地址:https://www.cnblogs.com/xckk/p/2667822.html
Copyright © 2011-2022 走看看