2012-11-28 02:23:39 markqian86 阅读数 2542
using UnityEngine;
using System.Collections;
using System;

public class ParabolaNode : MonoBehaviour 
{   
    //重力加速度
    public const float G = 9.8f;

    // 物体的初速度
    public float V0 {  set; get; }

    // 物体初速度与水平方向的夹角
    public float Sita { set; get; }

    // 最大射程
    public float Smax { set; get; }

    // 最大高度
    public float H { set; get; }

    // 运行时间
    public float T { set; get; }

    // 起点
    public Vector3 srcPos = new Vector3();

    // 目标
    public Vector3 dstPos = new Vector3();

    // 移动中
    public bool bMoving { set; get; }

    // 移动等待时间
    public float fWaitSecond { set; get; }

    //  高度限制
    public float fHighLimit { get; set; }

    void Update()
    {
        // wait
        if (fWaitSecond > 0)
        {
            fWaitSecond -= Time.deltaTime;
            return;
        }

        UpdateObj(Time.deltaTime);
    }

    public void Init(float fV0, float fSita, float fHigh, Vector3 vtDst, float fWait)
    {
        fWaitSecond = fWait;

        // 
        fHighLimit = fHigh;

        // 初始
        V0 = fV0;

        // 角度
        Sita = fSita;   // Mathf.PI / 4

        // 目标
        dstPos.x = vtDst.x;
        dstPos.y = vtDst.y;
        dstPos.z = vtDst.z;


        // 运行时间
        T = 2 * V0 * (float)Math.Sin(Sita) / G;

        // 最大高度
        H = V0 * V0 * (float)Math.Sin(Sita) * (float)Math.Sin(Sita) / (2 * G);

        // 最大射程
        Smax = 2 * V0 * V0 * (float)Math.Sin(Sita) * (float)Math.Cos(Sita) / G;
    }

    private float nowT = 0.0f;
    private void UpdateObj(float pass)
    {
        if (T < nowT)
            return;

        nowT += pass;

        // 水平坐标
        float x = V0 * (float)Math.Cos(Sita) * nowT;

        // 竖直坐标
        float y = V0 * (float)Math.Sin(Sita) * nowT - G * nowT * nowT / 2;


        Vector3 vt = gameObject.transform.localPosition;
        vt.x = (dstPos.x - srcPos.x) / Smax * x;
        vt.y = (fHighLimit / H -1) * y;
        double fAng = (double)Vector3.Angle(srcPos, dstPos);
        vt.z = (float)Math.Sin(fAng) * vt.x;

        gameObject.transform.localPosition = vt;
    }

}

2017-08-26 22:41:40 biezhihua 阅读数 1353

向量(又称矢量)是游戏开发过程中非常重要的概念,它是用于描述具有大小和方向两个属性的物理量,例如物体运动的速度、加速度、摄像机观察的方向、刚体受到的力都是向量。

在数学中,既有大小又有方向的量就是向量。在几何中,向量可以用一段有向线段来表示:
这里写图片描述

向量的运算

加减

向量的加法(减法)为各自分量分别相加(相减)。在物理上可以用来计算两个力的合力,或者几个速度分量的叠加。

数乘

向量与一个标量相乘为数乘。数乘可以对向量的长度进行缩放,如果标量大于0,那么向量的方向不变,若标量小于0,则向量的方向会变为反方向。

点乘(也称为数量积,还称为内积,英文叫做:Dot Product)

两个向量点乘得到一个标量,数值等于两个向量长度相乘后再乘以二者夹角的余弦。

通过两个向量点乘结果的符号可以快速的判断两个向量的夹角情况:

若u*v = 0,则向量u、v相互垂直。
若u*v > 0,则向量u、v夹角小于90度。
若u*v < 0,则向量u、v夹角大于90度。

叉乘(也称为向量积,还称为叉积,英文叫做:Cross Product)

两个向量的叉乘得到一个新的向量,新向量垂直于原来的两个向量,并且长度等于原来向量长度相乘后再乘夹角的余弦值。

叉乘不满足交换律,即a*b != b*a。

Vector3类

官方手册:https://docs.unity3d.com/ScriptReference/Vector3.html
中文API:http://www.ceeger.com/Script/Vector3/Vector3.html
源码:https://github.com/biezhihua/Unity3DTutorials/blob/master/Api/Vector3

magnitude (向量的模长

向量模长很简单分量平方相加再开根号,下面是其源码:

public static float Magnitude(Vector3 vector)
{
  return Mathf.Sqrt((float) ((double) vector.x * (double) vector.x + (double) vector.y * (double) vector.y + (double) vector.z * (double) vector.z));
}

normalized (单位化后的向量)

9.99999974737875E-06是科学计数法表示的,实际上是0.000009…

public static Vector3 Normalize(Vector3 value)
{
    float num = Vector3.Magnitude(value);
    if ((double) num > 9.99999974737875E-06)
        return value / num;
    return Vector3.zero;
}

规范化后的结果常常是:0,-1,1。
例如Vector3(-0.2,0,0)执行规范化,其num值是0.2,然后计算-0.2/0.2得到-1,那么最后的结果为(-1,0,0)。

Lerp(线性插值函数

使用Lerp函数,可以做到简单的缓动效果(物体A线性移动到B物体处)。

// Update is called once per frame
void Update () {
    transform.position =  Vector3.Lerp(start.position, end.position, Time.deltaTime);
}

虽然Lerp是线性插值函数,但是由于受到Time.deltaTime的影响会有小幅度变化,但是很细微,实际上不用考虑。

public static Vector3 Lerp(Vector3 a, Vector3 b, float t)
{
  t = Mathf.Clamp01(t);
  return new Vector3(a.x + (b.x - a.x) * t, a.y + (b.y - a.y) * t, a.z + (b.z - a.z) * t);
}

SmoothDamp

如果想让值改变的更平滑一些,可以使用此函数,它和Mathf.SmoothDamp()方法效果一致。

官方手册:https://docs.unity3d.com/ScriptReference/Vector3.SmoothDamp.html

[ExcludeFromDocs]
public static Vector3 SmoothDamp(Vector3 current, Vector3 target, ref Vector3 currentVelocity, float smoothTime)
{
 float deltaTime = Time.deltaTime;
 float maxSpeed = float.PositiveInfinity;
 return Vector3.SmoothDamp(current, target, ref currentVelocity, smoothTime, maxSpeed, deltaTime);
}

public static Vector3 SmoothDamp(Vector3 current, Vector3 target, ref Vector3 currentVelocity, float smoothTime, [DefaultValue("Mathf.Infinity")] float maxSpeed, [DefaultValue("Time.deltaTime")] float deltaTime)
{
 smoothTime = Mathf.Max(0.0001f, smoothTime);
 float num1 = 2f / smoothTime;
 float num2 = num1 * deltaTime;
 float num3 = (float) (1.0 / (1.0 + (double) num2 + 0.479999989271164 * (double) num2 * (double) num2 + 0.234999999403954 * (double) num2 * (double) num2 * (double) num2));
 Vector3 vector = current - target;
 Vector3 vector3_1 = target;
 float maxLength = maxSpeed * smoothTime;
 Vector3 vector3_2 = Vector3.ClampMagnitude(vector, maxLength);
 target = current - vector3_2;
 Vector3 vector3_3 = (currentVelocity + num1 * vector3_2) * deltaTime;
 currentVelocity = (currentVelocity - num1 * vector3_3) * num3;
 Vector3 vector3_4 = target + (vector3_2 + vector3_3) * num3;
 if ((double) Vector3.Dot(vector3_1 - current, vector3_4 - vector3_1) > 0.0)
 {
   vector3_4 = vector3_1;
   currentVelocity = (vector3_4 - vector3_1) / deltaTime;
 }
 return vector3_4;
}
2020-02-09 11:32:50 plm13581 阅读数 19

记录下自己的一些小功能
挂载到想要用哪个物体注视上
public class jintou : MonoBehaviour {

private Transform watchObject;	//需要注视的物体
private Transform m_amce;	//想要用哪个物体注视
private float speed = 8;		//围绕速度
public float vy;					//垂直偏移量
public float hx;				//垂直偏移量
private Vector3 wopon;	//存储注视的位置
// Use this for initialization
void Start () {
    m_amce = this.transform;	//获取要用哪个注视物体的变换组件
    //注视物体的变换组件
    watchObject = GameObject.Find("Cube").GetComponent<Transform>();
    wopon = watchObject.position;//获取注视物体的位置
    
}

// Update is called once per frame
void Update () {
    
    //按下鼠标右键
    if (Input.GetMouseButton(1))
    {
        //获取鼠标左右偏移量
        hx = Input.GetAxis("Mouse X");
        //RotateAround函数需要的参数(需要注视谁,延那个轴环绕旋转,转多少度)
        m_amce.RotateAround(wopon, Vector3.up, hx * speed);
        //获取鼠标上下偏移量
        vy = Input.GetAxis("Mouse Y");
       ////下面是限制上下角度代码
       //计算角度用rotatedAngle变量存储每次移动过后m_amce,x轴的角度
        float rotatedAngle = m_amce.eulerAngles.x + -vy * speed;
		//rotatedAngle变量小于15
        if (rotatedAngle < 15)
        {
        	//执行这行
            m_amce.RotateAround(wopon, m_amce.right, (-vy * speed) + (15 - rotatedAngle));
        }
        小于85执行这行
        else if (rotatedAngle > 85)
        {
       	
            //Mathf.Clamp
            m_amce.RotateAround(wopon, m_amce.right, 0);
        }
        //限制区域内执行这行
        else
        {
            m_amce.RotateAround(wopon, m_amce.right, -vy * speed);
        }
    }
}

}

2013-04-19 17:10:45 iteye_20251 阅读数 222

一、创建Unity项目

       打开Unity游戏编辑器界面,在导航菜单栏中选择File --->  New Project菜单项,在弹出界面中选择Create new Project页面,将项目名命名为MobilityModel,然后再点击Create Project,完成项目的创建。

       然后点击保存(Ctrl+S)保存场景。

 

二、构建模型

       在Hierarchy视图中分别创建游戏对象Plane(面板)、Cube(立方体)、Sphere(球体)、Cylinder(圆柱体)、Capsule(胶囊体),然后鼠标拖动创建的游戏对象将他们摆放在合适的位置。

       接下来在游戏中添加一个光源,在Hierarchy视图中选择Create--->Directional light菜单项,光源是游戏中非常重要的一个属性,一定要在游戏场景中设置它,如果不设置光源对象,Game视图会非常暗,严重影响游戏的效果。

 

三、添加脚本

       在Project视图中点击Create--->JavaScript菜单项创建一个游戏脚本,将其命名为MobilityModelScript.js,在脚本上编写如下代码:

//模型移动速度
var TranslateSpeed = 10;
//模型旋转速度
var RotateSpeed = 1000;
//绘制UI界面
function OnGUI(){
	//设置GUI背景色
    GUI.backgroundColor = Color.red;
	if(GUI.Button(Rect(10,10,70,30),"向左旋转")){
		//向左旋转
		transform.Rotate(Vector3.up * Time.deltaTime * (-RotateSpeed));
	}
	if(GUI.Button(Rect(90,10,70,30),"向前移动")){
		//向前移动
		transform.Translate(Vector3.forward * Time.deltaTime * TranslateSpeed);
	}
	if(GUI.Button(Rect(170,10,70,30),"向右旋转")){
		//向右旋转
		transform.Rotate(Vector3.up * Time.deltaTime * RotateSpeed);
	}
	if(GUI.Button(Rect(90,50,70,30),"向后移动")){
		//向后移动
		transform.Translate(Vector3.forward * Time.deltaTime * (-TranslateSpeed));
	}
	if(GUI.Button(Rect(10,50,70,30),"向左移动")){
		//向左移动
		transform.Translate(Vector3.right * Time.deltaTime * (-TranslateSpeed));
	}
	if(GUI.Button(Rect(10,50,70,30),"向右移动")){
		//向右移动
		transform.Translate(Vector3.right * Time.deltaTime * TranslateSpeed);
	}
	
	//显示模型位置信息
	GUI.Label(Rect(250,10,200,30),"模型位置"+transform.position);
	//显示模型旋转信息
	GUI.Label(Rect(250,50,200,30),"模型旋转"+transform.rotation);
}

      上述代码中重要方法和属性如下:

      OnGUI()方法用来绘制GUI界面组件。

      GUI.Button():设置一个按钮,返回true时表示该按钮被按下。

      GUI.Label():设置一个文本框。

      transform:为当前绑定模型的变换对象。

      transform.Rotate():设置模型旋转。

      transform.Translate():设置模型平移。

      Time.deltaTime:该数值为一个只读属性,不可修改,表示完成最后一帧的事件,单位为秒。

      Vector3:标志一个模型移动或者旋转的方法。

      Rect:规定一个矩形区域,用于显示控件。

      将编写好的脚本对象,将其从Project视图拖拽到Hierarchy视图中的立方体(Cube)对象上,如果没有提示错误,表示脚本绑定成功,运行游戏后该游戏对象将执行该脚本中的内容。

 

       目前立方体对象与其他模型对象之间是不存在碰撞的,但是运行游戏后,可以控制立方体(Cube)直接穿越另一个模型对象。为了让模型对象之间具有物理的碰撞,需要给模型对象添加一个刚体(Rigidbody)属性,添加方式:首先在Hierarchy视图中选中立方体对象,在Uinty导航菜单栏中选择Component --> Physics 

-->Rigidbody菜单项即可。

 

四、测试运行

       点击运行按钮就能看到结果,可以点击显示的六个按钮对象,可以移动Cube(立方体)的位置和旋转。


 

2017-05-23 22:14:25 qq_29859497 阅读数 278

unity3d简单变换移动


一切的外力都是向量,踢足球就相当于在足球上施加外力。外力会让物体做什么样的运动?根据牛顿运动定理,外力等于质量乘以加速度(F = ma)。外力能让物体加速,而对外力进行建模可以让我们根据各种运动定理模拟物体的运动状态。下面为一些简单例子,参数可自行更改。


简单随机移动:
    public float _speed = 1.0f;
    void Update () {
            transform.Translate (
                _speed * Random.Range(-0.03f,0.03f), 
                _speed * Random.Range(-0.03f,0.03f), 
                0);
    }

噪声旋转:
    public float _offset = 0.0f;//偏移量
    void Start () {
        _offset = 
            Time.realtimeSinceStartup;
    }
    void Update () {
        float time = Time.realtimeSinceStartup;
        float rotation = 
            Mathf.PerlinNoise (time, _offset);
        rotation = 360.0f * rotation - 180.0f;
        Quaternion direction= Quaternion.AngleAxis 
            (rotation , Vector3.forward);
        transform.localRotation = direction;
    }

简单随机变色:
void Update () {
        SpriteRenderer sr;
        sr = GetComponent<SpriteRenderer> ();
        Color cr = Random.ColorHSV ();
        cr.a = Random.Range (0.0f, 1.0f);
        sr.color = cr;
    }

简单随机缩放:
public float _speed = 1.0f;
void Update () {
        float X方向尺度变化 = 
             Random.Range (-0.01f, 0.01f);
        float Y方向尺度变化 = 
            Random.Range (-0.01f, 0.01f);
        transform.localScale +=
            new Vector3 (
                X方向尺度变化,
                Y方向尺度变化,
                0) * _speed;        
    }

简单随机旋转:
    public float _速率 = 10.0f;
    void Update () {
        float 旋转角度 = Random.Range (
            -_速率, _速率);
        transform.Rotate (
            Vector3.forward, 旋转角度);
    }

噪声随机移动:
    public float _速率 = 1.0f;
    public float _跨度 = 1.0f;
    void Update () {
        float X = 
            Mathf.PerlinNoise (
                _速率*Time.realtimeSinceStartup,
                0);
        float Y = 
            Mathf.PerlinNoise (
                _速率*Time.realtimeSinceStartup,
                10000.0f);
        transform.localPosition = 
            new Vector3 (X, Y, 0) * _跨度;

    }

噪声变色:
    private float[] _偏移量 = 
        new float[4]{0,0,0,0};
    void Start () {
        for (int i = 0; i < 4; i++) {
            _偏移量 [i] = 
                Random.Range (-100.0f, 100.0f);
        }
    }
    void Update () {
        SpriteRenderer sr = 
            GetComponent<SpriteRenderer> ();
        float 时刻 = Time.realtimeSinceStartup;
        Color 当前颜色 = sr.color;
        当前颜色.r = Mathf.PerlinNoise (
            时刻, _偏移量[0]);
        当前颜色.g = Mathf.PerlinNoise(
            时刻, _偏移量[1]);
        当前颜色.b = Mathf.PerlinNoise(
            时刻, _偏移量[2]);
        当前颜色.a = Mathf.PerlinNoise(
            时刻, _偏移量[3]);
        sr.color = 当前颜色;        
    }

Unity3d实现人物跳跃

阅读数 21548

Unity_3D数学基础_005

阅读数 563

没有更多推荐了,返回首页