视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
unity学习资料大全
2025-09-29 05:08:06 责编:小OO
文档
关于路径跟随设置点形成路径控制物体运动:

用过Torque3D的人都知道,在这个引擎中可以在编辑模式下设定路径 然后AI就会按照这个路径运动,现在unity3D也可以啦 分享给大家 希望能有点帮助~总共3个文件

把第一个个文件放在新建的gameobject上 例如cube,然后creat empty创建空object作为splineparent,再创建4个或者多个sphere1,2,3,4作为它的子物体,然后将splineparent拖到这个代码var SplineParent : GameObject中,最后会看到cube按照sphere1到4的顺序运动~

JavaScript - SplineController.js

enum eOrientationMode { NODE = 0, TANGENT }

var SplineParent : GameObject;

var Duration : float = 10.0;

var OrientationMode : eOrientationMode = eOrientationMode.NODE;

var WrapMode : eWrapMode = eWrapMode.ONCE;

var AutoStart : boolean = true;

var AutoClose : boolean = true;

var HideOnExecute : boolean = true;

private var mSplineInterp : SplineInterpolator = null;

private var mTransforms : Array = null;

@script AddComponentMenu("Splines/Spline Controller")

function OnDrawGizmos()

{

    var trans : Array = GetTransforms();

    

if (trans.length < 2)

        return;

    var interp = new SplineInterpolator();

    SetupSplineInterpolator(interp, trans);

    interp.StartInterpolation(null, false, WrapMode);

    

    var prevPos : Vector3 = trans[0].position;

for (c=1; c <= 100; c++)

    {

        var currTime:float = c * Duration / 100.0;

        var currPos = interp.GetHermiteAtTime(currTime);

        var mag:float = (currPos-prevPos).magnitude * 2.0;

        Gizmos.color = Color(mag, 0.0, 0.0, 1.0);

        Gizmos.DrawLine(prevPos, currPos);

        prevPos = currPos;

    }

}

function Start()

{

    mSplineInterp = gameObject.AddComponent(SplineInterpolator);

    

    mTransforms = GetTransforms();

    

    if (HideOnExecute)

        DisableTransforms();

    

    if (AutoStart)

        FollowSpline();

}

function SetupSplineInterpolator(interp:SplineInterpolator, trans:Array) : void

{

    interp.Reset();

    

    if (AutoClose)

        var step : float = Duration / trans.length;

    else

        step = Duration / (trans.length-1);

    

for (var c:int = 0; c < trans.length; c++)

    {

        if (OrientationMode == OrientationMode.NODE)

        {

            interp.AddPoint(trans[c].position, trans[c].rotation, step*c, Vector2(0.0, 1.0));

        }

        else if (OrientationMode == OrientationMode.TANGENT)

        {

            if (c != trans.length-1)

                var rot : Quaternion = Quaternion.LookRotation(trans[c+1].position - trans[c].position, trans[c].up);

            else if (AutoClose)

                rot = Quaternion.LookRotation(trans[0].position - trans[c].position, trans[c].up);

            else

                rot = trans[c].rotation;

                

            interp.AddPoint(trans[c].position, rot, step*c, Vector2(0.0, 1.0));

        }

    }

    if (AutoClose)

        interp.SetAutoCloseMode(step*c);

}

// We need this to sort GameObjects by name

class NameComparer extends IComparer 

{

    function Compare(trA : Object, trB : Object) : int {

        return trA.gameObject.name.CompareTo(trB.gameObject.name);

    }

}

//

// Returns children transforms already sorted by name

//

function GetTransforms() : Array

{

    var ret : Array = new Array();

    

    if (SplineParent != null)

    {

        // We need to use an ArrayList because there´s not Sort method in Array...

        var tempTransformsArray = new ArrayList();  

        var tempTransforms = SplineParent.GetComponentsInChildren(Transform);

        

        // We need to get rid of the parent, which is also returned by GetComponentsInChildren...

        for (var tr : Transform in tempTransforms)

        {

            if (tr != SplineParent.transform)

                tempTransformsArray.Add(tr);

        }

        

        tempTransformsArray.Sort(new NameComparer());

        ret = Array(tempTransformsArray);

    }

    

    return ret;

}

//

// Disables the spline objects, we generally don't need them because they are just auxiliary

//

function DisableTransforms() : void

{

    if (SplineParent != null)

    {

        SplineParent.SetActiveRecursively(false);

    }

}

//

// Starts the interpolation

//

function FollowSpline()

{   

if (mTransforms.length > 0)

    {

        SetupSplineInterpolator(mSplineInterp, mTransforms);

        mSplineInterp.StartInterpolation(null, true, WrapMode);

    }

}

JavaScript - SplineInterpolator.js

enum eEndPointsMode { AUTO = 0, AUTOCLOSED, EXPLICIT }

enum eWrapMode { ONCE = 0, LOOP }

private var mEndPointsMode = eEndPointsMode.AUTO;

class SplineNode

{

    var Point   : Vector3;

    var Rot     : Quaternion;

    var Time    : float;

    var EaseIO  : Vector2;

    

    function SplineNode(p:Vector3, quaternion, t:float, io:Vector2) { Point=p; Rot=q; Time=t; EaseIO=io; }

    function SplineNode(o : SplineNode) { Point=o.Point; Rot=o.Rot; Time=o.Time; EaseIO=o.EaseIO; }

}

private var mNodes : Array = null;

private var mState : String = "";

private var mRotations : boolean = false;

private var mOnEndCallback:Object;

function Awake()

{

    Reset();

}

function StartInterpolation(endCallback : Object, bRotations : boolean, mode : eWrapMode)

{   

    if (mState != "Reset")

        throw "First reset, add points and then call here";

        

    mState = mode == eWrapMode.ONCE? "Once" : "Loop";

    mRotations = bRotations;

    mOnEndCallback = endCallback;

    

    SetInput();

}

function Reset()

{

    mNodes = new Array();

    mState = "Reset";

    mCurrentIdx = 1;

    mCurrentTime = 0.0;

    mRotations = false;

    mEndPointsMode = eEndPointsMode.AUTO;

}

function AddPoint(pos : Vector3, quat : Quaternion, timeInSeconds : float, easeInOut : Vector2)

{

    if (mState != "Reset")

        throw "Cannot add points after start";

    

    mNodes.push(SplineNode(pos, quat, timeInSeconds, easeInOut));

}

function SetInput()

{   

if (mNodes.length < 2)

        throw "Invalid number of points";

    if (mRotations)

    {

for (var c:int = 1; c < mNodes.length; c++)

        {

// Always interpolate using the shortest path -> Selective negation

if (Quaternion.Dot(mNodes[c].Rot, mNodes[c-1].Rot) < 0)

            {

                mNodes[c].Rot.x = -mNodes[c].Rot.x;

                mNodes[c].Rot.y = -mNodes[c].Rot.y;

                mNodes[c].Rot.z = -mNodes[c].Rot.z;

                mNodes[c].Rot.w = -mNodes[c].Rot.w;

            }

        }

    }

    

    if (mEndPointsMode == eEndPointsMode.AUTO)

    {

        mNodes.Unshift(mNodes[0]);

        mNodes.push(mNodes[mNodes.length-1]);

    }

else if (mEndPointsMode == eEndPointsMode.EXPLICIT && (mNodes.length < 4))

        throw "Invalid number of points";

}

function SetExplicitMode() : void

{

    if (mState != "Reset")

        throw "Cannot change mode after start";

        

    mEndPointsMode = eEndPointsMode.EXPLICIT;

}

function SetAutoCloseMode(joiningPointTime : float) : void

{

    if (mState != "Reset")

        throw "Cannot change mode after start";

    mEndPointsMode = eEndPointsMode.AUTOCLOSED;

    

    mNodes.push(new SplineNode(mNodes[0] as SplineNode));

    mNodes[mNodes.length-1].Time = joiningPointTime;

    var vInitDir : Vector3  = (mNodes[1].Point - mNodes[0].Point).normalized;

    var vEndDir  : Vector3  = (mNodes[mNodes.length-2].Point - mNodes[mNodes.length-1].Point).normalized;

    var firstLength : float = (mNodes[1].Point - mNodes[0].Point).magnitude;

    var lastLength  : float = (mNodes[mNodes.length-2].Point - mNodes[mNodes.length-1].Point).magnitude;

    

    var firstNode : SplineNode = new SplineNode(mNodes[0] as SplineNode);

    firstNode.Point = mNodes[0].Point + vEndDir*firstLength;

    

    var lastNode : SplineNode = new SplineNode(mNodes[mNodes.length-1] as SplineNode);

    lastNode.Point = mNodes[0].Point + vInitDir*lastLength;

        

    mNodes.Unshift(firstNode);

    mNodes.push(lastNode);

}

private var mCurrentTime = 0.0;

private var mCurrentIdx = 1;

function Update ()

{   

if (mState == "Reset" || mState == "Stopped" || mNodes.length < 4)

        return;

            

    mCurrentTime += Time.deltaTime;

    // We advance to next point in the path

if (mCurrentTime >= mNodes[mCurrentIdx+1].Time)

    {

if (mCurrentIdx < mNodes.length-3)

        {

            mCurrentIdx++;

        }

        else

        {      

            if (mState != "Loop")

            {

                mState = "Stopped";

                

                // We stop right in the end point

                transform.position = mNodes[mNodes.length-2].Point;

                

                if (mRotations)

                    transform.rotation = mNodes[mNodes.length-2].Rot;

                

                // We call back to inform that we are ended

                if (mOnEndCallback != null)

                    mOnEndCallback();

            }

            else

            {

                mCurrentIdx = 1;

                mCurrentTime = 0.0;

            }

        }

    }

    

    if (mState != "Stopped")

    {

       // Calculates the t param between 0 and 1

        var param : float = (mCurrentTime - mNodes[mCurrentIdx].Time) / (mNodes[mCurrentIdx+1].Time - mNodes[mCurrentIdx].Time);                                                                                                                                                                                                                                                                                                                                                

    

        // Smooth the param

        param = MathUtils.Ease(param, mNodes[mCurrentIdx].EaseIO.x, mNodes[mCurrentIdx].EaseIO.y);

        

        transform.position = GetHermiteInternal(mCurrentIdx, param);

    

        if (mRotations)

        {

            transform.rotation = GetSquad(mCurrentIdx, param);

        }

    }

}

function GetSquad(idxFirstPoint : int, t : float) : Quaternion

{

    var Q0 : Quaternion = mNodes[idxFirstPoint-1].Rot;

    var Q1 : Quaternion = mNodes[idxFirstPoint].Rot;

    var Q2 : Quaternion = mNodes[idxFirstPoint+1].Rot;

    var Q3 : Quaternion = mNodes[idxFirstPoint+2].Rot;

    

    var T1 : Quaternion = MathUtils.GetSquadIntermediate(Q0, Q1, Q2);

    var T2 : Quaternion = MathUtils.GetSquadIntermediate(Q1, Q2, Q3);

    

    return MathUtils.GetQuatSquad(t, Q1, Q2, T1, T2);

}

function GetHermiteInternal(idxFirstPoint : int, t : float) : Vector3

{

    var t2 = t*t; var t3 = t2*t;

    

    var P0 : Vector3 = mNodes[idxFirstPoint-1].Point;

    var P1 : Vector3 = mNodes[idxFirstPoint].Point;

    var P2 : Vector3 = mNodes[idxFirstPoint+1].Point;

    var P3 : Vector3 = mNodes[idxFirstPoint+2].Point;

    

    var tension : float = 0.5;  // 0.5 equivale a catmull-rom

    

    var T1 : Vector3 = tension * (P2 - P0);

    var T2 : Vector3 = tension * (P3 - P1);

    

    var Blend1 : float =  2*t3 - 3*t2 + 1;

    var Blend2 : float = -2*t3 + 3*t2;

    var Blend3 : float =    t3 - 2*t2 + t;

    var Blend4 : float =    t3 -   t2;

    

    return Blend1*P1 + Blend2*P2 + Blend3*T1 + Blend4*T2;

}

function GetHermiteAtTime(timeParam : float) : Vector3

{   

if (timeParam >= mNodes[mNodes.length-2].Time)

        return mNodes[mNodes.length-2].Point;

    

for (var c:int = 1; c < mNodes.length-2; c++)

    {

if (mNodes[c].Time > timeParam)

            break;

    }

    

    var idx:int = c-1;

    var param : float = (timeParam - mNodes[idx].Time) / (mNodes[idx+1].Time - mNodes[idx].Time);                                                                                                                                                                                                                                                                                                                                        

    param = MathUtils.Ease(param, mNodes[idx].EaseIO.x, mNodes[idx].EaseIO.y);

    

    return GetHermiteInternal(idx, param);

}

JavaScript - MathUtils.js

class MathUtils

{

    //

    //

    //

    static function GetQuatLength(q : Quaternion) : float

    {

        return Mathf.Sqrt(q.x*q.x + q.y*q.y + q.z*q.z + q.w*q.w);   

    }

    

    //

    //

    //

    static function GetQuatConjugate(q : Quaternion) : Quaternion

    {

        return Quaternion(-q.x, -q.y, -q.z, q.w);

    }

    

    //

    // Logarithm of a unit quaternion. The result is not necessary a unit quaternion.

    // 

    static function GetQuatLog(q : Quaternion) : Quaternion

    {

        var res : Quaternion = q;

        res.w = 0;

    

if (Mathf.Abs(q.w) < 1.0)

        {      

            var theta : float = Mathf.Acos(q.w);

            var sin_theta : float = Mathf.Sin(theta);

if (Mathf.Abs(sin_theta) > 0.0001)

            {

                var coef:float = theta/sin_theta;

            res.x = q.x*coef;

            res.y = q.y*coef;

            res.z = q.z*coef;

      }

        }

     return res;

    }

    //

    // Exp

    //

    static function GetQuatExp(q : Quaternion) : Quaternion

    {

        var res : Quaternion = q;

        

        var fAngle:float = Mathf.Sqrt(q.x*q.x + q.y*q.y + q.z*q.z);    

        var fSin:float = Mathf.Sin(fAngle);

        

        res.w = Mathf.Cos(fAngle);

if (Mathf.Abs(fSin) > 0.0001)

        {

            var coef:float = fSin/fAngle;

            res.x = coef*q.x;

            res.y = coef*q.y;

            res.z = coef*q.z;

        }

        

        return res;

    } 

    //

    // SQUAD Spherical Quadrangle interpolation [Shoe87]

    //

    static function GetQuatSquad (t : float, q0 : Quaternion, q1 : Quaternion, a0 : Quaternion, a1 : Quaternion)

    {

        var slerpT:float = 2.0*t*(1.0-t);

    

        var slerpP = Slerp(q0, q1, t);

        var slerpQ = Slerp(a0, a1, t);

    

        return Slerp(slerpP, slerpQ, slerpT); 

    }

    static function GetSquadIntermediate (q0uaternion, q1uaternion, q2uaternion)

    {

        var q1Inv : Quaternion = GetQuatConjugate(q1);

        var p0 = GetQuatLog(q1Inv*q0);

        var p2 = GetQuatLog(q1Inv*q2);

        var sum : Quaternion = Quaternion(-0.25*(p0.x+p2.x), -0.25*(p0.y+p2.y), -0.25*(p0.z+p2.z), -0.25*(p0.w+p2.w));

    

        return q1*GetQuatExp(sum);

    }

    

    //

    // Smooths the input parameter t. If less than k1 ir greater than k2, it uses a sin. Between k1 and k2 it uses 

    // linear interp.

    //

    static function Ease(t : float, k1 : float, k2 : float) : float

    { 

      var f:float; var s:float; 

  

      f = k1*2/Mathf.PI + k2 - k1 + (1.0-k2)*2/Mathf.PI;

  

if (t < k1)

      { 

            s = k1*(2/Mathf.PI)*(Mathf.Sin((t/k1)*Mathf.PI/2-Mathf.PI/2)+1); 

      } 

      else 

if (t < k2)

      { 

            s = (2*k1/Mathf.PI + t-k1); 

      } 

      else 

      { 

            s= 2*k1/Mathf.PI + k2-k1 + ((1-k2)*(2/Mathf.PI))*Mathf.Sin(((t-k2)/(1.0-k2))*Mathf.PI/2); 

      } 

  

      return (s/f); 

    }

    

    //

    // We need this because Quaternion.Slerp always does it using the shortest arc

    //

    static function Slerp (p : Quaternion, q : Quaternion, t : float) : Quaternion

    {

        var ret : Quaternion;

        

        var fCos : float = Quaternion.Dot(p, q);

        

if ((1.0 + fCos) > 0.00001)

        {

if ((1.0 - fCos) > 0.00001)

            {

                var omega : float = Mathf.Acos(fCos);

                var invSin : float = 1.0/Mathf.Sin(omega);

                var fCoeff0  : float = Mathf.Sin((1.0-t)*omega)*invSin;

                var fCoeff1  : float = Mathf.Sin(t*omega)*invSin;

            }

            else

            {

                fCoeff0 = 1.0-t;

                fCoeff1 = t;

            }

            

            ret.x = fCoeff0*p.x + fCoeff1*q.x;

         ret.y = fCoeff0*p.y + fCoeff1*q.y;

         ret.z = fCoeff0*p.z + fCoeff1*q.z;

         ret.w = fCoeff0*p.w + fCoeff1*q.w;          

        }

        else

        {

            fCoeff0 = Mathf.Sin((1.0-t)*Mathf.PI*0.5);

            fCoeff1 = Mathf.Sin(t*Mathf.PI*0.5);

            

            ret.x = fCoeff0*p.x - fCoeff1*p.y;

         ret.y = fCoeff0*p.y + fCoeff1*p.x;

         ret.z = fCoeff0*p.z - fCoeff1*p.w;

         ret.w =  p.z;

        }

            

        return ret;

    }

    

}

Unity3D小地图代码

@script ExecuteInEditMode()

public var blip : Texture; //定義一個指針文件代表角色

public var radarBG : Texture; //地圖背景圖片,我直接用場景里我創建的render texture

public var centerObject : Transform; //選擇角色的物體的位置信息

public var mapScale = 0.3; //地圖縮放

public var mapCenter = Vector2(50,50); //地圖中心

function OnGUI () {

   

    bX=centerObject.transform.position.x * mapScale;

    bY=centerObject.transform.position.z * mapScale;

       

    bX=centerObject.transform.position.x * mapScale;

    bY=centerObject.transform.position.z * mapScale;

       

    GUI.DrawTexture(Rect(mapCenter.x-32,mapCenter.y-32,,),radarBG);

   // 上面的mapCenter.x-32是地圖的x位置,mapCenter.y-32是y位置,,是地圖的大小

    DrawBlipsForEnemies();

}

function DrawBlipsForCows(){

   

    var gos : GameObject[];

    gos = GameObject.FindGameObjectsWithTag("Cow");

    var distance = Mathf.Infinity;

    var position = transform.position;

    for (var go : GameObject in gos)  {

        drawBlip(go,blip);

    }

}

function drawBlip(go,aTexture){

   

    centerPos=centerObject.position;

    extPos=go.transform.position;

   

    dist=Vector3.Distance(centerPos,extPos);

    

    dx=centerPos.x-extPos.x; 

    dz=centerPos.z-extPos.z; 

   

    deltay=Mathf.Atan2(dx,dz)*Mathf.Rad2Deg - 270 - centerObject.eulerAngles.y;

   

    bX=dist*Mathf.Cos(deltay * Mathf.Deg2Rad);

    bY=dist*Mathf.Sin(deltay * Mathf.Deg2Rad);

   

    bX=bX*mapScale; 

    bY=bY*mapScale; 

   

if(dist<=200){

       GUI.DrawTexture(Rect(mapCenter.x+bX,mapCenter.y+bY,2,2),aTexture);

    }

}

function DrawBlipsForEnemies(){

   

    var gos : GameObject[];

    gos = GameObject.FindGameObjectsWithTag("Enemy");

    var distance = Mathf.Infinity;

    var position = transform.position;

    for (var go : GameObject in gos)  {

    drawBlip(go,blip);

    }

}

後半部份自己慢慢理解下,存為js文件即可使用

unity3d的动力学汽车脚本

这是从官网论坛上收集的一个汽车脚本,经过验证可以使用。由于skidmarks这个配套的脚本没有找到,所以把skidmarks相关的语句都屏蔽了,所以很遗憾没有刹车印的效果,其他的没有改。

    拿出来共享,感兴趣的一起研究下。

    汽车脚本代码看起来都比较复杂,主要是老外的编程底子牛,什么都写到代码里自动生成了。其实有些东西可以在编辑器里完成,这样就省不少代码了。还有制动和变速箱部分用了不少代码,这个可能要点汽车发动机知识,反正我是一点都没看懂。

    不想研究的可以直接拿来用。

    使用方法如下:

    1、把脚本直接连到汽车车身网格上,车身要有Rigidbody Component,要有四个轮子网格做子物体。 要想有声音的话还要有AudioSource Component。

    2、打开Inspector,选择汽车脚本,把四个轮子连接到相对应的Transform参数上。设置wheelRadius参数为你轮子网格的大小。WheelCollider是自动生成的,所以无需手动添加。这样就能保证运行了,其他的声音和灰尘可以再添加。

    脚本源代码如下:

#pragma strict

//maximal corner and braking acceleration capabilities 

var maxCornerAccel=10.0; 

var maxBrakeAccel=10.0;

//center of gravity height - effects tilting in corners 

var cogY = 0.0;

//engine powerband 

var minRPM = 700; 

var maxRPM = 6000;

//maximum Engine Torque 

var maxTorque = 400;

//automatic transmission shift points 

var shiftDownRPM = 2500; 

var shiftUpRPM = 5500;

//gear ratios 

var gearRatios = [-2.66, 2.66, 1.78, 1.30, 1.00]; 

var finalDriveRatio = 3.4;

//a basic handling modifier: 

//1.0 understeer 

//0.0 oversteer 

var handlingTendency = 0.7;

//graphical wheel objects 

var wheelFR : Transform; 

var wheelFL : Transform; 

var wheelBR : Transform; 

var wheelBL : Transform;

//suspension setup 

var suspensionDistance = 0.3; 

var springs = 1000; 

var dampers = 200; 

var wheelRadius = 0.45;

//particle effect for ground dust 

var groundDustEffect : Transform;

private var queryUserInput = true; 

private var engineRPM : float; 

private var steerVelo = 0.0; 

private var brake = 0.0; 

private var handbrake = 0.0; 

private var steer = 0.0; 

private var motor = 0.0; 

//private var skidTime = 0.0; 

private var onGround = false; 

private var cornerSlip = 0.0; 

private var driveSlip = 0.0; 

private var wheelRPM : float; 

private var gear = 1; 

//private var skidmarks : Skidmarks; 

private var wheels : WheelData[]; 

private var wheelY = 0.0; 

private var rev = 0.0;

//Functions to be used by external scripts 

//controlling the car if required 

//===================================================================

//return a status string for the vehicle 

function GetStatus(gui : GUIText) { 

   gui.text="v="+(rigidbody.velocity.magnitude * 3.6).ToString("f1") + " km/h\\ngear= "+gear+"\\nrpm= "+engineRPM.ToString("f0"); 

}

//return an information string for the vehicle 

function GetControlString(gui : GUIText) { 

   gui.text="Use arrow keys to control the jeep,\\nspace for handbrake."; 

}

//Enable or disable user controls 

function SetEnableUserInput(enableInput) 

   queryUserInput=enableInput; 

}

//Car physics 

//===================================================================

//some whee calculation data 

class WheelData{ 

   var rotation = 0.0; 

   var coll : WheelCollider; 

   var graphic : Transform; 

   var maxSteerAngle = 0.0; 

   var lastSkidMark = -1; 

   var powered = false; 

   var handbraked = false; 

   var originalRotation : Quaternion; 

};

function Start () { 

   //setup wheels 

   wheels=new WheelData[4]; 

for(i=0;i<4;i++)

      wheels[i] = new WheelData(); 

       

   wheels[0].graphic = wheelFL; 

   wheels[1].graphic = wheelFR; 

   wheels[2].graphic = wheelBL; 

   wheels[3].graphic = wheelBR;

   wheels[0].maxSteerAngle=30.0; 

   wheels[1].maxSteerAngle=30.0; 

   wheels[2].powered=true; 

   wheels[3].powered=true; 

   wheels[2].handbraked=true; 

   wheels[3].handbraked=true;

   for(w in wheels) 

   { 

      if(w.graphic==null) 

         Debug.Log("You need to assign all four wheels for the car script!"); 

      if(!w.graphic.transform.IsChildOf(transform))    

         Debug.Log("Wheels need to be children of the Object with the car script"); 

          

      w.originalRotation = w.graphic.localRotation;

      //create collider 

      colliderObject = new GameObject("WheelCollider"); 

      colliderObject.transform.parent = transform; 

      colliderObject.transform.position = w.graphic.position; 

      w.coll = colliderObject.AddComponent(WheelCollider); 

      w.coll.suspensionDistance = suspensionDistance; 

      w.coll.suspensionSpring.spring = springs; 

      w.coll.suspensionSpring.damper = dampers; 

      //no grip, as we simulate handling ourselves 

      w.coll.forwardFriction.stiffness = 0; 

      w.coll.sidewaysFriction.stiffness = 0; 

      w.coll.radius = wheelRadius; 

   }   

   //get wheel height (height forces are applied on) 

   wheelY=wheels[0].graphic.localPosition.y; 

    

   //setup center of gravity 

   rigidbody.centerOfMass.y = cogY; 

    

   //find skidmark object 

//   skidmarks = FindObjectOfType(typeof(Skidmarks)); 

    

   //shift to first 

   gear=1; 

}

//update wheel status 

function UpdateWheels() 

   //calculate handbrake slip for traction gfx 

    handbrakeSlip=handbrake*rigidbody.velocity.magnitude*0.1; 

if(handbrakeSlip>1)

      handbrakeSlip=1; 

       

   totalSlip=0.0; 

   onGround=false; 

   for(w in wheels) 

   {       

      //rotate wheel 

      w.rotation += wheelRPM / 60.0 * -rev * 360.0 * Time.fixedDeltaTime; 

      w.rotation = Mathf.Repeat(w.rotation, 360.0);       

      w.graphic.localRotation= Quaternion.Euler( w.rotation, w.maxSteerAngle*steer, 0.0 ) * w.originalRotation;

      //check if wheel is on ground 

      if(w.coll.isGrounded) 

         onGround=true; 

          

      slip = cornerSlip+(w.powered?driveSlip:0.0)+(w.handbraked?handbrakeSlip:0.0); 

      totalSlip += slip; 

       

      var hit : WheelHit; 

      var c : WheelCollider; 

      c = w.coll; 

      if(c.GetGroundHit(hit)) 

      { 

         //if the wheel touches the ground, adjust graphical wheel position to reflect springs 

         w.graphic.localPosition.y-=Vector3.Dot(w.graphic.position-hit.point,transform.up)-w.coll.radius; 

          

         //create dust on ground if appropiate 

if(slip>0.5 && hit.collider.tag=="Dusty")

         { 

            groundDustEffect.position=hit.point; 

            groundDustEffect.particleEmitter.worldVelocity=rigidbody.velocity*0.5; 

            groundDustEffect.particleEmitter.minEmission=(slip-0.5)*3; 

            groundDustEffect.particleEmitter.maxEmission=(slip-0.5)*3; 

            groundDustEffect.particleEmitter.Emit();                         

         } 

          

         //and skid marks             

/*if(slip>0.75 && skidmarks != null)

            w.lastSkidMark=skidmarks.AddSkidMark(hit.point,hit.normal,(slip-0.75)*2,w.lastSkidMark); 

         else 

            w.lastSkidMark=-1; */

      } 

     // else w.lastSkidMark=-1; 

   } 

   totalSlip/=wheels.length; 

}

//Automatically shift gears 

function AutomaticTransmission() 

if(gear>0)

   { 

if(engineRPM>shiftUpRPM&&gear         gear++; 

if(engineRPM1)

         gear--; 

   }

}

//Calculate engine acceleration force for current RPM and trottle 

function CalcEngine() : float 

   //no engine when braking 

if(brake+handbrake>0.1)

      motor=0.0; 

    

   //if car is airborne, just rev engine 

   if(!onGround) 

   { 

      engineRPM += (motor-0.3)*25000.0*Time.deltaTime; 

      engineRPM = Mathf.Clamp(engineRPM,minRPM,maxRPM); 

      return 0.0; 

   } 

   else 

   { 

      AutomaticTransmission(); 

      engineRPM=wheelRPM*gearRatios[gear]*finalDriveRatio; 

if(engineRPM         engineRPM=minRPM; 

if(engineRPM      { 

         //fake a basic torque curve 

         x = (2*(engineRPM/maxRPM)-1); 

         torqueCurve = 0.5*(-x*x+2); 

         torqueToForceRatio = gearRatios[gear]*finalDriveRatio/wheelRadius; 

         return motor*maxTorque*torqueCurve*torqueToForceRatio; 

      } 

      else 

         //rpm delimiter 

         return 0.0; 

   } 

}

//Car physics 

//The physics of this car are really a trial-and-error based extension of 

//basic "Asteriods" physics -- so you will get a pretty arcade-like feel. 

//This may or may not be what you want, for a more physical approach research 

//the wheel colliders 

function HandlePhysics () { 

   var velo=rigidbody.velocity; 

   wheelRPM=velo.magnitude*60.0*0.5;

   rigidbody.angularVelocity=new Vector3(rigidbody.angularVelocity.x,0.0,rigidbody.angularVelocity.z); 

   dir=transform.TransformDirection(Vector3.forward); 

   flatDir=Vector3.Normalize(new Vector3(dir.x,0,dir.z)); 

   flatVelo=new Vector3(velo.x,0,velo.z); 

   rev=Mathf.Sign(Vector3.Dot(flatVelo,flatDir)); 

   //when moving backwards or standing and brake is pressed, switch to reverse 

if((rev<0||flatVelo.sqrMagnitude<0.5)&&brake>0.1)

      gear=0; 

   if(gear==0) 

   {    

      //when in reverse, flip brake and gas 

      tmp=brake; 

      brake=motor; 

      motor=tmp; 

       

      //when moving forward or standing and gas is pressed, switch to drive 

if((rev>0||flatVelo.sqrMagnitude<0.5)&&brake>0.1)

         gear=1; 

   } 

   engineForce=flatDir*CalcEngine(); 

   totalbrake=brake+handbrake*0.5; 

if(totalbrake>1.0)totalbrake=1.0;

   brakeForce=-flatVelo.normalized*totalbrake*rigidbody.mass*maxBrakeAccel;

   flatDir*=flatVelo.magnitude; 

   flatDir=Quaternion.AngleAxis(steer*30.0,Vector3.up)*flatDir; 

   flatDir*=rev; 

   diff=(flatVelo-flatDir).magnitude; 

   cornerAccel=maxCornerAccel; 

if(cornerAccel>diff)cornerAccel=diff;

   cornerForce=-(flatVelo-flatDir).normalized*cornerAccel*rigidbody.mass; 

   cornerSlip=Mathf.Pow(cornerAccel/maxCornerAccel,3); 

    

   rigidbody.AddForceAtPosition(brakeForce+engineForce+cornerForce,transform.position+transform.up*wheelY); 

    

   handbrakeFactor=1+handbrake*4; 

if(rev<0)

      handbrakeFactor=1; 

   veloSteer=((15/(2*velo.magnitude+1))+1)*handbrakeFactor; 

   steerGrip=(1-handlingTendency*cornerSlip); 

if(rev*steer*steerVelo<0)

      steerGrip=1; 

   maxRotSteer=2*Time.fixedDeltaTime*handbrakeFactor*steerGrip; 

   fVelo=velo.magnitude; 

veloFactor=fVelo<1.0?fVelo:Mathf.Pow(velo.magnitude,0.3);

   steerVeloInput=rev*steer*veloFactor*0.5*Time.fixedDeltaTime*handbrakeFactor; 

if(velo.magnitude<0.1)

      steerVeloInput=0; 

if(steerVeloInput>steerVelo)

   { 

      steerVelo+=0.02*Time.fixedDeltaTime*veloSteer; 

if(steerVeloInput         steerVelo=steerVeloInput; 

   } 

   else 

   { 

      steerVelo-=0.02*Time.fixedDeltaTime*veloSteer; 

if(steerVeloInput>steerVelo)

         steerVelo=steerVeloInput; 

   } 

   steerVelo=Mathf.Clamp(steerVelo,-maxRotSteer,maxRotSteer);    

   transform.Rotate(Vector3.up*steerVelo*57.295788); 

}

function FixedUpdate () { 

   //query input axes if necessarry 

   if(queryUserInput) 

   { 

      brake = Mathf.Clamp01(-Input.GetAxis("Vertical")); 

      handbrake = Input.GetButton("Jump")?1.0:0.0; 

      steer = Input.GetAxis("Horizontal"); 

       motor = Mathf.Clamp01(Input.GetAxis("Vertical")); 

    } 

   else 

   { 

      motor = 0; 

      steer = 0; 

      brake = 0; 

      handbrake = 0; 

   }

   //if car is on ground calculate handling, otherwise just rev the engine 

    if(onGround) 

      HandlePhysics(); 

   else 

      CalcEngine();    

       

   //wheel GFX 

   UpdateWheels();

   //engine sounds 

   audio.pitch=0.5+0.2*motor+0.8*engineRPM/maxRPM; 

   audio.volume=0.5+0.8*motor+0.2*engineRPM/maxRPM; 

}

//Called by DamageReceiver if boat destroyed 

function Detonate() 

   //destroy wheels 

   for( w in wheels ) 

      w.coll.gameObject.active=false;

   //no more car physics 

   enabled=false; 

}

@script RequireComponent (Rigidbody) 

@script RequireComponent (AudioSource)

漂浮效果

using UnityEngine;

using System.Collections;

public class Floater : MonoBehaviour {

    public float waterLevel, floatHeight;

    public Vector3 buoyancyCentreOffset;

    public float bounceDamp;

   

   

    void FixedUpdate () {

        Vector3 actionPoint = transform.position + transform.TransformDirection(buoyancyCentreOffset);

        float forceFactor = 1f - ((actionPoint.y - waterLevel) / floatHeight);

       

if (forceFactor > 0f) {

            Vector3 uplift = -Physics.gravity * (forceFactor - rigidbody.velocity.y * bounceDamp);

            rigidbody.AddForceAtPosition(uplift, actionPoint);

        }

    }

}

输入文字时让人物停止不动

var playName = "None";

static var currentControl ;

function Update() { 

        

   if( currentControl) 

                return;//当有任何输入框被点击时屏蔽之后的内容

        

        if (Input.GetKey(KeyCode.UpArrow)||Input.GetKey(KeyCode.W)){

                transform.Translate(Vector3.forward*0.5);

        }

        if (Input.GetKey(KeyCode.DownArrow)||Input.GetKey(KeyCode.S)){

                transform.Translate(Vector3.forward*-0.5);

        }

        if (Input.GetKey(KeyCode.LeftArrow)||Input.GetKey(KeyCode.A)){

                transform.Rotate(Vector3.down *2);

        }

        if (Input.GetKey(KeyCode.RightArrow)||Input.GetKey(KeyCode.D)){

                transform.Rotate(Vector3.up *2);

        }

function OnGUI(){

        playName = GUI.TextField(Rect(10,10,100,20),playName);

        //当鼠标按在除输入框的 任意位置时

        if( Input.GetMouseButtonDown( 0 ) && GUIUtility.hotControl == 0 ) 

                GUIUtility.keyboardControl = 0; 

                

        currentControl = GUIUtility.keyboardControl ;

}

ps:不管输入框在那个Scrpit中,只要在想屏蔽的地方的OnGUI加上面的代码就行,        

if( Input.GetMouseButtonDown( 0 ) && GUIUtility.hotControl == 0 ) 

                GUIUtility.keyboardControl = 0;不用重复加入。

动态加载贴图或模型

var mesh1 : GameObject;   

function Start()   

{   

   mesh1 = Instantiate(Resources.Load("model"));                                                  //加载模型   

   mesh1.transform.position=Vector3(1020,14,720);                                      //模型出现的位置   

}   

function Update ()    

{   

   renderer.material.mainTexture = Resources.Load("a");                                 //加载材质   

}  下载本文

显示全文
专题