2016-04-11 13:50:45 u014528558 阅读数 2104
  • DOTween插件API详解及案例实现

     游戏制作中少不了一些简单又有趣的动画。要完成这些动画,使用插件是最快最有效的解决方案了,DOTween插件功能基本涵盖了常用动画效果的所有需求。本课程详细讲解了DOTween插件的API使用及示例动画效果的实现,并附上API使用文档,方便以后查看。作为游戏开发中常用插件之一,DOTween以高效、简洁的优势被越来越多的Unity开发人员青睐。想要全面了解这款插件的小伙伴们,速速学起来吧!   Unity版本:2018.2.17   寄语:学会珍惜每个今天,才能拥有无悔的明天。

    960 人正在学习 去看看 张增会

前言

喜❤欢❤请❤点❤赞

 

编程习惯

  1. 代码命名和书写规则可以参考alibaba tx netease都有出手册..这个很重要是共同开发的基础
  2. 单个类内容太多的时候,可以用partial分隔类
  3. 参数多的时候,可以封装为一个struct
  4. if else太长的时候,可以多换行能一次写完的都写在一起
  5. 不要在参数内嵌套方法 考虑到单行长度和debug的时候不知道错误出在哪里

使用Visual Studio作为编辑器

●安装 --- unity2017以后的版本,不自带Mono了,但安装Unity时可勾选安装vs,安装vs也可勾选安装Unity,官方互gay
●调试 --- 如果不会,必须学习,调试是快速debug的重要方法。vs可一键Unity断点调试,改完代码F5Unity那边也跑起来了

                          
●快捷键 --- 修改快捷键ctrl+w关闭当前窗口的方法,照着这样改成你自己的习惯,希望vs啥时候出个设置保存云..
●搜索 --- 使用“ Ctrl + ; ”  打开可以搜索类和方法,输入栏右方设置搜索是否包括方法;使用“ Ctrl+T/, ”可以搜索脚本内的方法
                    
●阅读 --- 可以使用使用 #region和#endregion,用于代码的缩放,对于代码阅读编辑相当好。
●标签 --- 灵活使用标签例如//TODO就可以标注将会做(其实是骗自己...)之后可以在 视图→任务列表 查看              
●DLL --- vs还可以生成解决方案DLL,然后拉过去或代码功能自动复制一份到UnityAsset内就可以给Unity使用了

 

Unity常用API

  1. 物体旋转和位移
    //3D旋转:
    (瞬间)
    transform.localRotation = Quaternion.Euler(new Vector3(x,y,z));
    transform.rotation = Quaternion.AngleAxis(30, Vector3.up);//绕轴旋转正方向30
    (缓慢目标)
    transform.rotation = Quaternion.Slerp( a , b , Time.deltime * speed);
    (缓慢速度)
    mRotaX = transform.localEulerAngles.x;
    mRotaY = transform.localEulerAngles.y;
    mRotaZ = transform.localEulerAngles.z;
    float deltaAngle = CommonData.DeltaTime * AngleSpeed;
    mRotaZ += deltaAngle;
    transform.localRotation = Quaternion.Euler(mRotaX, mRotaY, mRotaZ);
    (角度转换)
    Vector3 rotationVector3 = new Vector3(0f, 30f, 0f);
    Quaternion rotation = Quaternion.Euler(rotationVector3);
    transform.rotation = rotation;
    Quaternion.eulerAngles直接输出Quaternion的Vector3值
    --------------------- 
    //3D位移:
    (方向)
    transform.Translate(Vector3.back * FallingSpeed);
    transform.position = Vector3.MoveTowards(transform.position,tempUpdatePos, 
                          Time.deltaTime * DisShakeThreshold);
    (固定时间)
    transform.Translate(Vector3.normalize(tarPos-selfPos) *
             (Vector3.Distance(selfPos,tarPos)/(setTime * Time.deltime)));
    --------------------- 
    //2D方向移动:
    moveDirection = mTarget.transform.position - mSelf.transform.position;
    moveDirection.Normalize();
    float target = Mathf.Atan2(moveDirection.y, moveDirection.x) * Mathf.Rad2Deg - 90f;
    mSelf.transform.rotation = 
    Quaternion.Slerp(mSelf.transform.rotation,  
    Quaternion.Euler(0, 0, target), turnSpeed * Time.deltaTime);
    _controller.SetForce(speedX,speedY));
    DOTween
     
  2. 按键Input
    void Update()
        {
            if (Input.GetKey("up"))
            {
                print("up arrow key is held down");
            }
    
            if (Input.GetKey("down"))
            {
                print("down arrow key is held down");
            }
        }
  3. OnGui按钮 与 Log
    void OnGUI()
        {
            if (GUI.Button(new Rect(10, 10, 150, 100), "I am a button"))
            {
                Debug.Log("<color=#9400D3> You clicked the button! </color>");
                //green 绿色	#008000ff    red 红色	#ff0000ff
                //white 白色	#ffffffff	 yellow 黄色	#ffff00ff
             
                /*转义符
                \’               单引号符 
                \”               单引号符 
                \\                反斜线符"\" 
                \n                换行
                \r                 回车 
                text在运行后\会自动变成了\\,所以无效解决方法:
                msgText.text = msg.Replace("\\n", "\n");
                */
            }
        }
  4. 资源加载

    资源加载API分为Editor下的和非Editor下的  其他平台路径各有区别
    //作为重要功能 深入研究会发现坑很多
     
    /*********************Editor******************/
    //1.Resource文件夹
    //同步
    GameObject prefab = Resources.Load("资源路径/名字") as GameObject;
    GameObject go = Instantiate(prefab) as GameObject;
    //异步
    Resources.LoadAsync<Object>(path);
    //2.非Resourece
    //路径为 Assets/XX/XX.prefab 这样的格式
    UnityEditor.AssetDatabase.LoadAssetAtPath<T>(path);
    /*********************非Editor的其他******************/
    AssetBundle bundle = AssetBundle.LoadFromFile(path);
    Object obj = bundle.LoadAsset<GameObject>("XXXX");
  5. U3D射线射碰撞体与层

    //(检测是否碰撞)
    if (Physics.Raycast(origin, Vector3.down, 1f,1 << LayerMask.NameToLayer("Ground")))
    {
        //层的说明
        //int 1-31是未转化的层index 而用于射线LayerMask 是1<<int 运算后的 是一个很大的数
        // 1 << 10 打开第10的层。 等价于 1 << LayerMask.NameToLayer("Ground");
        //~(1 << 10) 打开除了第10之外的层。
        //~(1 << 0) 打开所有的层。
        //(1 << 10) | (1 << 8) 打开第10和第8的层。等价于 LayerMask.GetMask(("Ground", "Wall");
    }
    //(输出信息的)
    Ray ray = new Ray(transform.position, Vector3.down);
    RaycastHit hitInfo = new RaycastHit();
    if (Physics.Raycast(ray, out hitInfo, 30f, layerMask))
    {
        Debug.Log(hitInfo.point);
    }
    //物体
    gameObject.layer = (1-31层 或 LayerMask.NameToLayer("Ground"));
    //发射碰撞体
    Physics.OverXXX

    在Unity中每个GameObject都有Layer属性,默认的Layer都是Default。在Unity中可编辑的Layer共有24个(8—31层),官方已使用的是0—7层,默认不可编辑!

    LayerMask实际上是一个位码操作,在Unity3D中一共有32个Layer层,并且不可增加。

    位运算符
    按位运算符:~、|、&、^。位运算符主要用来对二进制位进行操作。

    逻辑运算符:&&、||、!。逻辑运算符把语句连接成更复杂的复杂语句。

    按位运算符:左移运算符<<,左移表示乘以2,左移多少位表示乘以2的几次幂。

  6. 协程IEnumerator
    void Start(){
        StartCoroutine(Test());
    }
    IEnumerator Test()
    {
        yield return null; // 下一帧再执行后续代码
        yield return 0; //下一帧再执行后续代码
        yield return 6;//(任意数字) 下一帧再执行后续代码
        yield break; //直接结束该协程的后续操作
        yield return asyncOperation;//等异步操作结束后再执行后续代码
        yield return StartCoroution(/*某个协程*/);//等待某个协程执行完毕后再执行后续代码
        yield return WWW();//等待WWW操作完成后再执行后续代码
        yield return new WaitForEndOfFrame();//等待帧结束,等待直到所有的摄像机和GUI被渲染完成后,在该帧显示在屏幕之前执行
        yield return new WaitForSeconds(0.3f);//等待0.3秒,一段指定的时间延迟之后继续执行,在所有的Update函数完成调用的那一帧之后(这里的时间会受到Time.timeScale的影响);
        yield return new WaitForSecondsRealtime(0.3f);//等待0.3秒,一段指定的时间延迟之后继续执行,在所有的Update函数完成调用的那一帧之后(这里的时间不受到Time.timeScale的影响);
        yield return WaitForFixedUpdate();//等待下一次FixedUpdate开始时再执行后续代码
        yield return new WaitUntil()//将协同执行直到 当输入的参数(或者委托)为true的时候....如:yield return new WaitUntil(() => frame >= 10);
        yield return new WaitWhile()//将协同执行直到 当输入的参数(或者委托)为false的时候.... 如:yield return new WaitWhile(() => frame < 10);
    }
  7. Animator
    Animator可以被继承!
    Animator可以添加脚本处理状态!

    重置动画(播放动画第一帧)
    firstAnimName = GetComponent<Animator>().GetCurrentAnimatorClipInfo(0)[0].clip.name;
    GetComponent<Animator>().Play (firstAnimName,-1,0); 

    获取某个动画名字的时间长度
    private Animator animator;
    public void GetLengthByName(string name){
        float length = 0;
        AnimationClip[] clips = animator.runtimeAnimatorController.animationClips;
        foreach(AnimationClip clip in clips)    {
            if(clip.name.Equals(name))        {
                length = clip.length;            break;
            }
        }    Debug.Log(length);
    }
  8. 刚体

    Mass:质量(kg)
    Drag:空气阻力 越大越难推动
    Angular Drag:旋转阻力  越大越不会旋转 0无阻力 10以后基本无惯性
    Use Gravity:是否使用重力

    Constraints
    Freeze Position:锁定位置
    Freeze Rotation:锁定旋转
     
  9. 物体碰撞

    Edit-Project Settings-Physics 打开物理管理器(Physics Manager)里面可以设置层级相互间的碰撞
    碰撞条件是都带Collider 其中一个带rigidbody

    //触发器
    MonoBehaviour.OnTriggerEnter(Collider collider)当进入触发器
    MonoBehaviour.OnTriggerExit(Collider collider)当退出触发器
    MonoBehaviour.OnTriggerStay(Collider collider)当逗留触发器
     
    //碰撞信息检测:
    MonoBehaviour.OnCollisionEnter(Collision collision) 当进入碰撞器
    MonoBehaviour.OnCollisionExit(Collision collision) 当退出碰撞器
    MonoBehaviour.OnCollisionStay(Collision collision)  当逗留碰撞器

     

  10. 平台预处理
    #if UNITY_EDITOR  
        platform = "hi,大家好,我是在unity编辑模式下";  
    #elif UNITY_SERVER
    #elif UNITY_IPHONE  
        platform="hi,大家好,我是IPHONE平台";  
    #elif UNITY_ANDROID  
        platform="hi,大家好,我是ANDROID平台";  
    #elif UNITY_STANDALONE_OSX  
    #elif UNITY_STANDALONE_WIN  
        platform="hi,大家好,我是Windows平台";  
    #endif  
        Debug.Log("Current Platform:" + platform);  
  11. DoFile 读取一个Txt
    string localConfig = Application.dataPath + "/Config/123.txt";
    if (File.Exists(localConfig))
    {
        string[] strs = File.ReadAllLines(localConfig);
    }
  12. Editor

    选中物体保存为预设
    	[UnityEditor.MenuItem("Tools/Apply Selected Prefabs")]
    	static void ApplySelectedPrefabs(){
    		//获取选中的gameobject对象
    		GameObject [] selectedsGameobject= Selection.gameObjects;		
    		GameObject prefab = PrefabUtility.FindPrefabRoot (selectedsGameobject[0]);		
    		for (int i = 0; i < selectedsGameobject.Length; i++) {
    			GameObject obj=selectedsGameobject[i];			
    			UnityEngine.Object newsPref= PrefabUtility.GetPrefabObject(obj);			
    			//判断选择的物体,是否为预设
    			if(PrefabUtility.GetPrefabType(obj)  == PrefabType.PrefabInstance){				
    				UnityEngine.Object parentObject = PrefabUtility.GetPrefabParent(obj); 				
    				//string path = AssetDatabase.GetAssetPath(parentObject);//获取路径
    PrefabUtility.ReplacePrefab(obj,parentObject,ReplacePrefabOptions.ConnectToPrefab);//替换预设					
    				AssetDatabase.Refresh();//刷新
    			}	
    		}		
    	}


     
  13. Inspector面板自定义
    用代码重新绘制了Inspector,并赋值,所以注意不能使用Ctrl+Z
    [CustomEditor(typeof(你的代码))]
    public class 你的代码Editor : Editor
    {
        SerializedObject myScript;
        SerializedProperty bool变量;
        SerializedProperty 任意变量;
        SerializedProperty 数组变量;
    
        void OnEnable()
        {
            myScript = new SerializedObject(target);
            bool变量 = myScript.FindProperty("bool变量");
            任意变量 = myScript.FindProperty("任意变量");
            数组变量 = myScript.FindProperty("数组变量");
        }
    
        public override void OnInspectorGUI()
        {
            base.OnInspectorGUI();
            myScript.Update();
            if (bool变量.boolValue)
            {
                EditorGUILayout.LabelField("面板提示");
                EditorGUILayout.PropertyField(任意变量);
            }
            else
            {
                EditorGUILayout.LabelField("面板提示");
                数组变量.arraySize = EditorGUILayout.IntField("Length", 数组变量.arraySize);
                for (int i = 0; i < 数组变量.arraySize; i++)
                    EditorGUILayout.PropertyField(数组变量.GetArrayElementAtIndex(i));
            }
            myScript.ApplyModifiedProperties();
        }
    }
  14.  

  15. 画线画圆画弧
    ①Debug.DrawLine

    public float radius;
    public float angle;
    public int smooth = 20;
    public Vector3 dir = Vector3.right;
    public bool drawSide = true;
    
    void Update()
    {
        Vector3 start = Quaternion.Euler(0, 0, -angle) * dir * radius;
        Vector3 firstPos = Vector3.zero;
        Vector3 lastPos = Vector3.zero;
        for (int i = 0; i <= smooth; i++)
        {
            firstPos = transform.position + Quaternion.Euler(0,0,(angle*2/smooth)*i)*start;
            lastPos = transform.position + Quaternion.Euler(0,0,(angle*2/smooth)*(i+1))*start;
            Debug.DrawLine(firstPos, lastPos, Color.red);
        }
        if (drawSide)
        {
            Debug.DrawLine(transform.position, transform.position + start, Color.red);
            Debug.DrawLine(transform.position, lastPos, Color.red);
        }
    }


    ②LineRender

    private LineRenderer line;//画线
    line = this.gameObject.AddComponent<LineRenderer>();
    //只有设置了材质 setColor才有作用
    line.material = new Material(Shader.Find("Particles/Additive"));
    line.SetVertexCount(2);//设置两点
    line.SetColors(Color.yellow, Color.red); //设置直线颜色
    line.SetWidth(0.1f, 0.1f);//设置直线宽度
    
    //设置指示线的起点和终点
    line.SetPosition(0, start.position);
    line.SetPosition(1, end.position);
    
    public float R;//半径
    public int N;//不要超过45
    
    line.SetVertexCount(N+1);//这里要加1,达成闭合曲线
    for (int i = 0; i < N + 1; i++)
    {
      float x = R * Mathf.Cos((360 / N * i) * Mathf.Deg2Rad) + transform.position.x; //确定x坐标
      float z = R * Mathf.Sin((360 / N * i) * Mathf.Deg2Rad) + transform.position.z; //确定z坐标
      line.SetPosition(i, new Vector3(x, transform.position.y, z));         
    }

     

  16. 控制全局音量
    通过 AudioListener.volume来控制场景场景音量
    Unity推出了自己声音引擎
    也可以用热门的引擎 如:Wwise..
     
  17. UGUI

    进度条 -- 通过改变UI的FillAmount值 UnityEngine.UI.Image healthBar.fillAmount = 0.0f;

    艺术字体 -- 对于Text 使用材质和Outline可以制作

    Mask -- 可以遮挡 对于制作一些动画比较好

    自动排列用 Layout Group 如果要适配改变大小 都要加Content Size Fitter 要改变的设置为preferred size;
     

  18. Unity播放透明动画

    ①UnityAnimation播放,直接全选png序列帧图(卡超级久) 然后拖到面板上(卡很久),会自动生成序列播放的animator。但我发现超过300图之后有可能会出现不明报错(大概因为输出问题),1k张感觉就没什么希望了,最重要的是在unity里1080p的图转成sprite,都会变成10m一张,导致项目发布之后更是奇大无比。
    ②播放mov,可以尝试播带透明通道的mov,但需要一个shader,具体我不会写,在网上找到的也不太好用,各种问题(抠色会失真和有噪点,提取透明or黑白遮罩会出现不同步
    LoadResources,先load资源文件夹内的,然后播放。load的东西如果超过2G(C#设定)则不能加载
    ④LoadAssets。因为是一张张地load,不会出现太大而不加载的问题。目前使用这个办法播放

  19. Lighting

    设置窗口(Window->Lighting->Settings)是主要控制unity全局光照(GlobalIllumination GI)的地方。尽管GI的默认设置已经有了很好的效果,lighting设置面板的一些属性可以调节GI处理的很多方面,从而可以定制场景或者优化场景的质量、速度和存储空间。窗口还包括环境光、光晕、雾效、烘焙的设置。

    可使用Class.UnityEngine.RenderSettings代码改变这些

  20. Debug
    日志路径 C:\Users\Administrator\AppData\LocalLow\DefaultCompany
  21. 待续..
     

Unity特性

1.unity具有特殊意义的文件夹

link

2.unity时间函数执行顺序

3.持续更新;

 

C#相关API

  1. Only one exe只允许打开一个程序
    int count=Process.GetProcessesByName(Process.GetCurrentProcess().ProcessName).Length ;
    if (count> 1)
    {
        // MessageBox.Show(count.ToString());调试使用    
        Process.GetCurrentProcess().Kill();//杀掉当前
    }

     

  2.  启动一个进程
     

    一个C#的API  可以用于打开一个网页..应用..或者进程..或者控制面板内的功能..例如打印..

    public void PrintFile()
    {
        System.Diagnostics.Process process = new System.Diagnostics.Process(); //系统进程
        process.StartInfo.CreateNoWindow = false; //不显示调用程序窗口
        process.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;//
        process.StartInfo.UseShellExecute = true; //采用操作系统自动识别模式
        process.StartInfo.FileName=path; //要打印的文件路径
        process.StartInfo.Verb="print"; //指定执行的动作,打印:print打开:open…………
        process.Start(); //开始打印
    }

     

  3. 改变鼠标位置和隐藏鼠标
     

    using System.Runtime.InteropServices;
    [DllImport("user32.dll")]
    public static extern int SetCursorPos(int x, int y);
    Void XX(){ SetCursorPos(0, 0);  }
    [DllImport("user32.dll")] 
    public static extern int SetCursorPos(int x, int y); 
    void Start () 
    {
        //隐藏
        Cursor.visible = false;
    }
  4.  

 

数学相关

向量与夹角与三角函数

//U3D  Vector3.forward 实际是(0,0,1) 向前的意思 也就是右上角Z轴方向
//forward是蓝色箭头方向 back是反方向  right是红色箭头方向 left反之 up是绿色箭头方向 down反之

Vector3 vector = targetPos - originPos;//任意两点向量 = V3目标位置 - V3起点位置
float angle = Vector3.Angle(from, to); //向量夹角 v3.angle(向量A,向量B)
Vector3.Normalize;//单位向量

//Deg2Rad 度转弧度 ; Rad2Deg 弧度转度
//求角度的三角函数值
Mathf.Sin(Mathf.Deg2Rad * angle);
//求变长求角度
Mathf.Atan2(y,x) * Mathf.Rad2Deg;

 

 

其他

  1. uLua使用方法

    注意AppConst里的LuaBundleModel变量,如果想使用AssetBundle模式,该值置为true,但是每次修改lua代码,需要执行菜单栏上的LuaFramework->Build XXX Resource,将lua资源打包,否则,你修改的lua逻辑不会更新并执行。

    如果LuaBundleModel置为false,则lua代码会时时更新。

    此外,修改C#代码,一定不要忘了执行菜单Lua->Clear wrap files,然后重新生成Gen Wrap + Binder

    确定逻辑无误后,注册C#类,打开"CustomSettings.cs",注册我们的类。"_GT(typeof(XXXXXX)),"。最后,执行上面第2步的Lua->Clear wrap files,Gen Wrap + Binder。此时,会生成一个叫MyHelloWorldWrap.cs的文件,在Assets\LuaFramework\ToLua\Source\Generate目录下,其实所有在CustomSettings中注册的C#类都会生成Wrap文件,保存在该目录下。

  2. Windows工具
    项目同步一般用svn或git主要是免费 大公司用收费的软件
    AutoHotKey作为快捷键操作打开
     
  3. Mac鸡工具 

    连接:可以使用vnc viewer
    项目管理:Cornerstone

  4. 持续更新...

 

2017-08-10 12:44:13 u011360242 阅读数 3845
  • DOTween插件API详解及案例实现

     游戏制作中少不了一些简单又有趣的动画。要完成这些动画,使用插件是最快最有效的解决方案了,DOTween插件功能基本涵盖了常用动画效果的所有需求。本课程详细讲解了DOTween插件的API使用及示例动画效果的实现,并附上API使用文档,方便以后查看。作为游戏开发中常用插件之一,DOTween以高效、简洁的优势被越来越多的Unity开发人员青睐。想要全面了解这款插件的小伙伴们,速速学起来吧!   Unity版本:2018.2.17   寄语:学会珍惜每个今天,才能拥有无悔的明天。

    960 人正在学习 去看看 张增会

Unity3D常用API总结

一. MonoBehaviour类及查询API

MonoBehaviour是每个脚本的基类.

MonoBehaviour常用方法及调用顺序

   //最开始调用,做一些初始化工作。建议少用,此刻物体可能还没有实例化出来,会影响程序执行顺序。
    void Awake(){}
    // 不是很紧急的初始化,一般放在Start里面来做。仅在Update函数第一次被调用前调用。
    void Start(){}
    //用户点击检视面板的Reset按钮或者首次添加该组件时被调用。此函数只在编辑模式下被调用。Reset最常用于在检视面板中给定一个最常用的默认值。
    void Reset(){}
    // 每一帧调用一次,帧间隔时间有可能改变。
    void Update(){}
    //以相同时间间隔调用,用在力学更新效果中。执行在Update之前。
    void FixedUpdate(){}
    //在Update和FixedUpdate调用之后调用。一般人物的移动放在Update中,而摄像机的跟进变化放到FixedUpdate中。确保两个独立,一前一后,不产生错误。
    void LateUpdate(){}

    //On开头的方法,是由其他事件触发调用的。
    //物体被删除时调用
    void OnDestroy(){}
    //物体启用时被调用
    void OnEnable(){}
    //物体被禁用时调用
    void OnDisable(){}
    //这个函数会每帧调用好几次(每个事件一次),GUI显示函数只能在OnGUI中调用
    void OnGUI(){}

下图是单个脚本内部方法的调用顺序:
这里写图片描述

查询API:游戏蛮牛Unity3D-API

二. Input类及脚本字段属性在检视面板中的运用

输入系统的接口.
getaxis、getkey、getbutton、getjoystick等函数。

为了提高输入方式在代码中的效率,推荐用GetButton()方法,而不是GetKey().GetButton根据不同的设备进行对应的按键输入,比如手柄,PC,手机 etc.

Unity中定制按钮的方式
Edit–>project setting–>Input
具体按键设定规则见:Unity圣典Input输入

GetKey()、GetKeyDown()、GetKeyUp()方法:

    // 每一帧调用一次,帧间隔时间有可能改变。
    void Update()
    {
        //KeyCode为枚举类
        //GetKey方法:只要按下就会执行 直到不按 执行不止一次
        Input.GetKey(KeyCode.A);
        //GetKeyDown:按下按键执行 执行一次
        Input.GetKeyDown(KeyCode.A);
        //GetKeyDown:按下后松开按键执行 执行一次
        Input.GetKeyUp(KeyCode.A);
        //以上方法返回布尔值
    }

GetButton()、GetButtonDown()、GetButtonUp()方法:

    // 每一帧调用一次,帧间隔时间有可能改变。
    void Update()
    {
        //GetButton方法括号中的值为buttonName(按钮别称) 可在相关文档中查阅
        //GetButton方法:只要按下就会执行 直到不按 执行不止一次
        Input.GetButton("Jump");
        //GetButtonDown:按下按键执行 执行一次
        Input.GetButtonDown("Jump");
        //GetButtonDown:按下后松开按键执行 执行一次
        Input.GetButtonUp("Jump");
        //以上方法返回布尔值
    }

GetAxis() 获取轴

根据坐标轴名称返回虚拟坐标系中的值。
使用控制器和键盘输入时此值范围在-1到1之间。如果坐标轴设置为鼠标运动增量,鼠标增量乘以坐标轴灵敏度的范围将不是-1到1 。

C#脚本:

// A very simplistic car driving on the x-z plane.
// 一个十分简单的在x-z平面的驾车例子
using UnityEngine;
using System.Collections;

public class example : MonoBehaviour {
    public float speed = 10.0F;//移动速度
    public float rotationSpeed = 100.0F;//旋转速度

    void Update() {
        // Get the horizontal and vertical axis.
        //获取横向和纵向坐标轴
        // By default they are mapped to the arrow keys.
        //默认情况下他们关联到方向键上
        // The value is in the range -1 to 1
        //值的范围是在-1到1之间
        float translation = Input.GetAxis("Vertical") * speed;
        float rotation = Input.GetAxis("Horizontal") * rotationSpeed;

        // Make it move 10 meters per second instead of 10 meters per frame...
        // 使它每帧移动10米变为每秒移动10米...
        translation *= Time.deltaTime;
        rotation *= Time.deltaTime;

        // Move translation along the object's z-axis
        //沿着z轴平移对象
        transform.Translate(0, 0, translation);

        // Rotate around our y-axis
        //以我们的y轴为中心旋转
        transform.Rotate(0, rotation, 0);
    }
}
// Performs a mouse look.
//执行一个鼠标观察
using UnityEngine;
using System.Collections;

public class example : MonoBehaviour {
    public float horizontalSpeed = 2.0F;
    public float verticalSpeed = 2.0F;
    void Update() {
        // Get the mouse delta. This is not in the range -1...1
        //获取鼠标增量,范围不在-1...1
        float h = horizontalSpeed * Input.GetAxis("Mouse X");
        float v = verticalSpeed * Input.GetAxis("Mouse Y");
        transform.Rotate(v, h, 0);
    }
}

GetJoystickNames() 获取控制杆名称列表

返回一个用来描述已连接的控制杆的字符串集合。
它可以用在用户输入设置界面 –这样,你就可以把显示的标签”Joystick 1”换成意义更明确的名字像”Logitech WingMan”,读取不同控制器的值,你需要分别为各个控制器的数字指定指方向轴如果你想将其使用在输入设置中。

C#脚本:

// Prints a joystick name if movement is detected.
//如果检测到移动就输出一个控制杆名称
using UnityEngine;
using System.Collections;

public class example : MonoBehaviour {
    void Update() {
        // requires you to set up axes "Joy0X" - "Joy3X" and "Joy0Y" - "Joy3Y" in the Input Manger
        //你需要在输入管理器中设置方向轴"Joy0X" - "Joy3X""Joy0Y" - "Joy3Y"
        int i = 0;
        while (i < 4) {
            if (Mathf.Abs(Input.GetAxis("Joy" + i + "X")) > 0.2F || Mathf.Abs(Input.GetAxis("Joy" + i + "Y")) > 0.2F)
                Debug.Log(Input.GetJoystickNames()[i] + " is moved");

            i++;
        }
    }
}

脚本字段属性在检视面板中的运用:

// Prints a joystick name if movement is detected.
//如果检测到移动就输出一个控制杆名称
using UnityEngine;
using System.Collections;

public class example : MonoBehaviour {
    //public修饰的变量可以在检视面板中显示
    //private修饰的不能显示

    //可以显示的GameObject类型的数组 
    //在检视面板中有Size(数组大小)和Element(元素)两个属性
    public GameObject[] gameObject = new GameObject[10];

    //可以显示的一个Rigidbody类型的变量
    public Rigidbody rigidbody = new Rigidbody();

    //不能显示的string类型字符串
    private string NPCName = "Max";

    //可以显示的int类型数值
    public int Score = 11;

    //自动补全 在脚本中定义的初始值会在检视面板中显示
    public int Number { get; set; }

    void strat(){}
    void update(){}
}

三.Time类及单例模式实现

常用Time.deltaTime

在Update/LateUpdate中打印Time.deltaTime时间是不固定的,是一个动态变化值,是前两帧之间时间的差值。

在FixedUpdate中打印Time.deltaTime时间是固定的。

deltaTime() 增量时间

以秒计算,完成最后一帧的时间(只读)。
使用这个函数使和你的游戏帧速率无关。

放在Update()函数中的代码是以帧来执行的.如果我们需要物体的移动以秒来执行.我们需要将物体移动的值乘以Time.deltaTime。

如果你加或减一个每帧改变的值,你应该与Time.deltaTime相乘。当你乘以Time.deltaTime实际表示:每秒移动物体10米,而不是每帧10米。

当从MonoBehaviour的FixedUpdate里调用时,返回固定帧速率增量时间(fixedDeltaTime)。

请注意从OnGUI里你不应该依赖于Time.deltaTime,因为OnGUI可以在每帧被多次调用并且每个调用deltaTime将持有相同的值,直到下一帧再次更新。

C#脚本:

using UnityEngine;
using System.Collections;

public class example : MonoBehaviour {
    void Update() {
        // Move the object 10 meters per second!
        //每秒移动物体10米
        float translation = Time.deltaTime * 10;
        transform.Translate(0, 0, translation);
    }
}

单例模式singleton

单例仅允许被实例一次,这就保证了他在各个程序模块间的唯一性。

//一般使用单例模式时,类名可能为GameManager
//通常用于控制游戏流程 哪个关卡 哪一步 角色信息的记录
//排行榜 积分表等
//在游戏中,单例模式一般在数据的保存和读取时用到
private static ModelLocator instance;
public static ModelLocator getInstance{
    get{
        if(instance==null){
            instance=new ModelLocator();
        }
        return instance;
    }
}

详细的Unity中单例模式的应用,百度”Unity中的单例模式”
二周目的时候详细补充在这

四.GameObject类和对象,多种查找GO的方法

gameObject(g小写)代表当前脚本挂载的游戏对象本身。
若使用this.xxx的话调用的是脚本本身而不是游戏对象

GameObject(G大写)代表游戏对象类。

查找GO并赋值Find族函数:

private GameObject go;

go = GameObject.Find(“Cube”);//根据名字查找对象

go = GameObject.FindGameObjectWithTag(string tag);//根据标签查找

go.activeSelf 游戏物体是否被激活(true or false)

go.activeInHierarchy 游戏物体所处层级的父级是否被激活(true or false)


理解游戏组件和游戏对象的关系

创建一个cube,并不是创建一个cube对象,而是创建了挂载着filter和renderer组件的对象


五.Destroy方法和Transform对象(包括对象移动)

Destroy方法:

销毁一个游戏物体。
Destroy(go);
Destroy(go, 3);//等待3s销毁

Transform对象:

位置transform.position(注意是小写t,是monobehaviour类中的默认字段,表示当前脚本挂在的游戏物体的transform信息)

旋转transform.rotation
缩放transform.scale
向量及运算 Vector3

在Unity中为左手坐标系
这里写图片描述

移动对象:

Transform.Translate

Transform.Rotate

transform.position.x获取x轴坐标

Mathf.PingPong 乒乓
让数值t在 0到length之间往返。t值永远不会大于length的值,也永远不会小于0。
返回值将在0和length之间来回移动。

//Mathf.PingPong 乒乓 例子
using UnityEngine;
using System.Collections;

public class example : MonoBehaviour {
    void Update() {
    // Set the x position to loop between 0 and 3
    //设置x位置循环在0和3之间
        transform.position = new Vector3(Mathf.PingPong(Time.time, 3), transform.position.y, transform.position.z);
    }
}

六.Lerp插值运算

插值运算:位置Vector3.Lerp 旋转Vector3.Slerp
Quaternion targetrotation = Quaternion.LookRotation(player.position - transform.position);
//根据初始和目标位置计算出对应的旋转角度

插值运算不仅仅可以作为位置、旋转、缩放等计算,还可以做为灯光亮度等的差值计算,也就是说只要是从一个确定状态渐进过渡到另一个确定状态的计算,都可以用到插值运算。
位置插值:三维向量
Vector3 targetpostion = player.position + new Vector3(0, 2.42f, -2.42f);
transform.position = Vector3.Lerp(transform.position, targetpostion, speed * Time.deltaTime);
旋转插值:三维角度
Quaternion targetrotation = Quaternion.LookRotation(player.position - transform.position);
transform.rotation = Quaternion.Slerp(transform.rotation, targetrotation, speed * Time.deltaTime);
灯光亮度插值:浮点值
public float newIntensity = 5;
light.intensity = Mathf.Lerp(light.intensity, newIntensity, speed * Time.deltaTime);
//light.intensity位当前灯光的值
颜色插值:
Color.Lerp(currentColor, newColor, speed * Time.deltaTime);
其他比如Material.Lerp、Mathf.InverseLerp等,可以通过查手册了解。

七.Instantiate实例化prefab对象

所有的C#对象都是继承于object类,包括int、float这些函数类型,当然也包括Monobehaviour、GameObject这些类。

static function Instantiate(original: Object, position: Vector3, rotation: Quaternion): Object;

public GameObject Spawn() 
{
    /* 生成prefab的实例化,因为默认是object类型,所以需要强转为GameObject */
    return GameObject.Instantiate(prefab, transform.position, transform.rotation) as GameObject;
}

其他方法:
GameObject.GetComponent:通过游戏物体获取其组件
CharacterController cc = this.GetComponent();
Animator animator = this.GetComponent();
Component.GetComponent:通过游戏物体的组件获取其其他组件Transform player = GameObject.FindGameObjectWithTag(Tags.player).transform;
PlayerATKAndDamage playerAtkAndDamage = player.GetComponent();
//PlayerATKAndDamage是一个脚本AddForce:添加力AddTurque:添加扭矩

八.协同(协程)以及yield

一般用来在脚本中增加延时效果。因为在Start()或者Update()中是不能直接延时的(WaitForSecond())等待某个操作结束之后再执行代码字符串做为参数:

void Start () 
{
    StartCoroutine("DoSomething", 2.0);
    yield WaitForSeconds (1);//可以在任意位置使用yield语句。yield的返回值控制何时恢复协同程序向下执行。这里等待1s之后才会接着执行下面的语句。
    StopCoroutine("DoSomething");
}

void DoSomething (float someParameter) 
{
    while (true) 
    {
        print("DoSomething Loop");
        // 停止协同程序的执行并返回到主循环直到下一帧.
        yield;
    }
}

IEnumerator做为参数:

IEnumerator Start()
{
    StartCoroutine("DoSomething", 2.0F); //StartCoroutine(DoSomething(2.0F)); 使用IEnumerator做参数不能用StopCoroutine停用。
    yield return new WaitForSeconds(1);
    StopCoroutine("DoSomething"); //请注意只有StartCoroutine使用一个字符串方法名时才能用StopCoroutine停用之。
}

IEnumerator DoSomething(float someParameter)
{
    while (true) {
        print("DoSomething Loop");
        yield return null;
    }
}

开启协同:
StartCoroutine(string methodName):字符串作为参数可以开启线程并在协程结束前终止线程;开启协程时最多只能传递一个参数,并且性能消耗会更大一点
StartCoroutine(IEnumerator routine):只能等待协程的结束而不能随时终止(除非使用StopAllCoroutines()方法)
中止协同:
StopCoroutine(string methodName):中止一个协同,只能终止该MonoBehaviour中的协同程序
StopAllCoroutines():中止所有协同,只能终止该MonoBehaviour中的协同程序
将协同程序所在gameobject的active属性设置为false,当再次设置active为ture时,协同程序并不会再开启。

yield

yiled:和协同密切相关的一个概念,一个协同程序在执行过程中,可以在任意位置使用yield语句。yield的返回值控制何时恢复协同程序向下执行。
yield不可单独使用

  需要与return配合使用,例如:

  1 yield return 0; //等0帧

  2 yield return 1; //等1帧

  3 yield return WaitForSeconds(3.0); //等待3秒

 4 yield return null;//立即返回调用点

  所有使用yield的函数必须将返回值类型设置为IEnumerator类型,例如:
  

IEnumerator DoSomeThingInDelay() {...}

当然,你也可以把Start()返回值定义为IEnumerator类型,那么在Start里面也可以使用yield延时返回,但不推荐这样做:

IEnumerator Start()
{
    StartCoroutine("DoSomething", 2.0F); //StartCoroutine(DoSomething(2.0F)); 使用IEnumerator做参数不能用StopCoroutine停用。
    yield return new WaitForSeconds(1);
    StopCoroutine("DoSomething"); //请注意只有StartCoroutine使用一个字符串方法名时才能用StopCoroutine停用之。
}

你也可以把StartCoroutine和yiled return结合起来使用,保证函数执行顺序,这样调用能保证,init1,init2,init3一个一个的执行,不至于出现后面执行的代码引用一个前面未初始化的变量:

IEnumerator Init()
{
    yield return StartCoroutine(init1());
    Debug.Log("init1 finish");
    yield return StartCoroutine(init2());
    Debug.Log("init2 finish");
    yield return StartCoroutine(init3());
    Debug.Log("init3 finish");
}

IEnumerator init1()
{
    // 模拟初始化
    yield return new WaitForSeconds(2);//
}
IEnumerator init2()
{
    // do somthing..
    yield return new WaitForSeconds(2);//
}
IEnumerator init2()
{
    // do somthing..
    yield return new WaitForSeconds(2);//
}

相关的api总结文章有:
个人开发Unity3d游戏中常用API函数

2017-11-07 20:17:04 dongkaixuan 阅读数 2266
  • DOTween插件API详解及案例实现

     游戏制作中少不了一些简单又有趣的动画。要完成这些动画,使用插件是最快最有效的解决方案了,DOTween插件功能基本涵盖了常用动画效果的所有需求。本课程详细讲解了DOTween插件的API使用及示例动画效果的实现,并附上API使用文档,方便以后查看。作为游戏开发中常用插件之一,DOTween以高效、简洁的优势被越来越多的Unity开发人员青睐。想要全面了解这款插件的小伙伴们,速速学起来吧!   Unity版本:2018.2.17   寄语:学会珍惜每个今天,才能拥有无悔的明天。

    960 人正在学习 去看看 张增会

常用API(重点)

Ø  介绍: 应用程序编程接口,是一些预先定义的函数

Unity引擎提供了丰富的组件和类库,为开发者提供了非常大的便利,苏联从、掌握和使用这些API对于游戏开发效率提高很重要

Ø  注意:

1.组件都不能now,如果需要为物体添加组件,调用物体的AddComponent方法

2.所有附加到物体上的类,必须继承自Component

Component

Ø  常用属性:gameObject  transform colliderrenderer

Ø  常用方法: GetComponentGetComponentInChildren GetComponentInparent

Ø  小练习:

  方法    (调用方法的是游戏对象,不是类)

       private void Start()

       {           //this 表示该游戏对象

           //附加到2个物体中,问:获取到的是哪个物体的位置?

             Vector3 pos = this.transform.position;

           Debug.Lod(pos);//?先获取第1个对象的位置,再获取第2个对象的位置

        }

       private void OnGUI()

        {

           if(GUILayout.Button("GetComponent"))//运行时在Unity生成一个按钮,点击运行1次下边代码

           {  //GetComponent : 在当前物体中根据类型查找组件

               //修改当前物体颜色     脚本对象-->组件对象-->属性

          this.GetComponent<MeshRenderer>().material.color = color.red

               //结论:获取1个组件引用,即可获取其他类型组件引用

           }

            if(GUILayout.Button("GetComponent"))

           {                //在当前物体中查找所有组件

               Var all Component = this.GetComponents<Component>();

               foreach(var item in allComponent)

               {

                    Debug.Lod(item);

               }

               var allScript = this.GetComponents<MonoBehaviour>();//查找所有脚本。脚本都继承于MonoBehaviour类,找儿子就写到父亲

               foreach(var item in allScript)

               {

                    Debug.Lod(item);

               }

           }

        if(GUILayout.Button("GetComponent"))

          {  //从自身开始查找 所有后代物体指定类型组件

           var renderer = GetComponentInChildern<MeshRenderer>();

           //从自身开始查找 所有先辈物体指定类型组件

           var renderer = GetComponentInParent<MeshRenderer>();

           }

        }

Transform

Ø  简述:提供设置位置方位+/(在、移动,自传,围绕旋转,注释旋转)

查找(根据名字,索引找子物体,父,根物体)功能。

Ø  Transform组件的成员变量

Ø  Transform组件的成员函数

Ø  应用示例:

1.  向前方移动

2.  绕自身坐标轴y轴旋转

3.  绕世界坐标轴的y轴旋转

4.  使相机观察方向跟随物体移动

Ø  课堂小练习:

public classTransformDemo02 : MonoBehaviour

{

    public Transform target;

    public string childName;

    private void OnGUI()

    {

        #region 位置、方位相关

        //相对于世界坐标系的坐标

        Vector3 worldPos = transform.position;

        //相对于父物体的坐标[编译器中显示]

        Vector3 localPos =transform.localPosition;

        //相对于父物体的缩放比例[编译器中显示]

        Vector3 localScale =transform.localScale;

        //理解为:相对于模型的缩放比例(父物体.localScale * 当前物体.localScale)

        Vector3 lossyScale =transform.lossyScale;

        if (GUILayout.Button("向前移动1m(自身)"))

        {

            //沿自身坐标系移动

            transform.Translate(0, 0,1);//translate:调动

        }

        if (GUILayout.Button("向前移动1m(世界)"))//每一帧执行一次

        {

            //沿世界坐标系移动

            transform.Translate(0, 0, 1,Space.World);

        }

        if (GUILayout.RepeatButton("沿y轴旋转1度(自身)"))

        {

            //沿自身坐标系旋转

            transform.Rotate(0, 1, 0);

        }

        if (GUILayout.RepeatButton("沿y轴旋转1度(世界)"))

        {

            //沿世界坐标系旋转

            transform.Rotate(0, 1, 0,Space.World);

        }

        if(GUILayout.RepeatButton("LookAt"))

        {

            //注视旋转(z轴指向目标物体位置)

            transform.LookAt(target);

        }

        if(GUILayout.RepeatButton("RotateAround"))

        {

            //围绕旋转(围绕的点,围绕的轴,旋转角度)

           transform.RotateAround(target.position, Vector3.right, 1);

        }

        #endregion

 

        #region 查找

        if (GUILayout.Button("根据名字查找子物体"))

        {

            //需求:获取某个子物体的MeshRenderer组件

            //名称 --> 变换组件 --> 其他组件

            Transform tf =transform.Find(childName);  //只能查找孩子

           tf.GetComponent<MeshRenderer>().material.color = Color.red;

            //缺点:限制物体层级关系

            //建议:通过方法递归查找某个后代物体

            //transform.Find("子物体/子物体")

        }

        if (GUILayout.Button("根据索引查找子物体"))//通过索引查找,索引的顺序与Unity面板顺序一致

        {

            //transform.childCount 子物体数量

            //需求:获取所有子物体(第一代)

            for (int i = 0; i <transform.childCount; i++)

            {

                Transform childTF = transform.GetChild(i);

            }

        }

        //获取父物体

        Transform parentTF =transform.parent;

        //设置父物体

        //transform.SetParent(父物体变换组件);

        //获取根物体    根物体:指层级最顶层的物体

        Transform root = transform.root;

        #endregion

    }

}

 

GameObject

简述:提供了对物体操作(创建,激活、禁用,查找(标签))功能

注意:小写的是对象引用(gameobject)大写的是类名(GameObject)

小练习:

   public class GameObjectDemo03 : MonoBehaviour

{

    //变量:

    //activeInHierarchy 物体在场景中激活状态

    //activeSelf  物体自身激活状态

    //如果父物体被禁用,子物体在场景中也被禁用。

    //此时,子物体activeInHierarchy为false,activeSelf为true

    public GameObject targetGO;

    private void OnGUI()

    {

        //需求:禁用/启用物体

        if (GUILayout.Button("禁用/启用物体"))

        {

           targetGO.SetActive(!targetGO.activeInHierarchy);

        }

        //需求:创建红色的聚光灯

        if (GUILayout.Button("创建红色的聚光灯"))

        {

            GameObject go = newGameObject("MyLight");

            Light light =go.AddComponent<Light>();

            light.color = Color.red;

            light.type = LightType.Spot;

        }

        if (GUILayout.Button("创建红色的聚光灯"))

        {

            //场景中物体往往过多,所以 慎用  。

            //GameObject go01 =GameObject.Find("物体名称");

          

            //根据标签查找单一物体

            GameObject playerGO = GameObject.FindWithTag("Player");

            //查找使用指定标签的所有物体

            GameObject[] allEnemy =GameObject.FindGameObjectsWithTag("Enemy");

        }

    }

Object类(提供了 功能)

简述:Unity中能用的东西都叫object

 

归纳4个常用类,查找方法

 Component类: 查找组件(父物体、根物体、根据名称、索引查找子物体)

    GetComponent:当前物体根据类型找组件 

       this.GetComponent<MeshRenderer>().material.color= Color.red;

    GetComponents:当前物体中查找所有组件

        varallComponent = this.GetComponents<Component>();

    GetComponentChildern:从自身开始找所有后代物体指定类型组件

        var rendererChildern =this.GetComponentChildern<MeshRenderer>();

    GetComponentParent:自身开始查找所有先辈指定类型组件

   varrendererParent = this.GetComponentParent<MeshRenderer>();

Transform类: 查找变换组件(父物体、根物体、根据名称、索引查找子物体)

根据名字查找物体:

   transform.Find("子物体/子物体")

          Transform tf = transform.Find(childName);//只能查找孩子

根据索引查找子物体:

   Transform childTF02 = transform.GetChild(0); //根据索引

Transform[] childTF = newTransform[transform.childCount];  //获取所有     

    for(inti=0;i<transform.childCount;i++)

    {

       childTF = transform.GetChild(i);

    }

    查找物体

    Transform parentTF = transform.parent;

    查找物体

    Transform root = transform.root;

GameObject类:通过标签、名字查找游戏对象, GetComponent查找组件(当前物体、先辈、后代)

    根据标签查找单一物体:

    GameObject playerGo = GameObject.FindWithTag("player");

    查找使用指定标签所有物体:

    GameObject[] allEnemy = GameObject.FindGameObjectsWithTag("Enemy");

object类:  查找对象(组件 物体) 根据类型

     //获取指定类型所有对象

            //FindObjectsOfType<Enemy>()

            FindObjectsOfType<Enemy>();

      //获取指定类型一个对象

            //FindObjectOfType<Player>()

 

Time

简述:ity中可以通过Time类用来获取时间有关的信息,可以用来计算帧速率调整时间流逝速度等功能

恒定的速度: 如果在渲染帧运动,必须在速度上乘以每帧间隔,以得到恒定速度

例如: transform.Rotate(0,Time.deltaTime*speed,0)

时间缩放(整体游戏进度):

实质:影响 fixedUpdete 执行频率

结论:不影响 Update 执行频率(不影响渲染) 影响 Time.deltaTime

游戏暂停为0 游戏继续为 1 游戏快进为 2 游戏慢动作 0.5

Time.TimeScale=值?

 

 

Time类的成员变量:

预制件Prefab (倒计时练习)

Ø  一种资源类型,可以多次在场景进行实例

Ø  优点:对预设制件的修改,可以同步到所有实例,从而提高开发效率

Ø  如果单独修改实例的属性值,则改值不在随预制件变化

Ø  Select键:通过预制件实例选择对应预制件

Ø  Revert键:放弃实例属性值,还原预制件属性值

Ø  Apply键:将某一实例的修改应用到所有实例中

Ø  需求:使用Text制作倒计时预制件,从02:00开始,最后10秒字体为红色,时间为00:00后停止计时

 //**********************方案一******************************

//重点:①定义下次修改时间②当到达时间③执行逻辑④在当前时间上累加一秒

//语法重点:  Time.time(游戏开始当前的真实时间)

//            string.Format("占位符",变量)(在Unity中用占位符需要使用)

private Text textTimer;

     publicint num = 120;

     voidStart()

     {

        textTimer = GetComponent<Text>();

     }

     voidUpdate()

     {

        Timer();

     }

    private float nextTimer = 1;

     void Timer()

     {

         if(nextTimer <= Time.time)

         {

            num--;

            textTimer.text = string.Format ("{0:d2},{1:d2}", num / 60, num% 60);

            nextTimer = Time.time + 1;

         }

         if(num <= 10)

         {

            textTimer.color = Color.red;

         }

     }

//**********************方案二******************************

//重点:①定义用于记录累加时间的变量②累加每帧间隔③当时间到了④执行逻辑⑤清零记录累加时间的变量

//语法重点:   Time.deltaTime(上一帧所有的时间 、也就是每帧间隔时间) 

private int num = 120;

private Text textTimer;

private float newTimer;

public float intervalTimer=1;

void Start()

{

   textTimer = GetComponent<Text>();

}

 

void Update()

{

   Timer();

}

 

void Timer()

{

   newTimer += Time.deltaTime;

    if(newTimer >= intervalTimer)

    {

       num--;

       textTimer.text=string.Format("{0:d2}:{1:d2}", num / 60, num %60);

       newTimer = 0;

    }

}  

//**********************方案三******************************

//语法重点: 【重复调用】   InvokeRepeating(“方法名称”,开始执行时间,间隔)

//           【延迟调用】   Invoke("方法名称",开始执行时间)

//           【取消调用】   CancelInvoke(“方法名”) 

privateText textTimer;

privatefloat num = 120;

publicfloat intervalTimer=1;

publicfloat startTimer = 1;

voidStart()

{

 textTimer =GetComponent<Text>();

 InvokeRepeating("Timer", 1, 1);

}

 

void Timer()

{

    num--;

    textTimer.text =string.Format("{0}:{1}", num / 60, num % 60);

    if (num == 0)

    {

        CancelInvoke("Timer");

    }

}

Random类

简述:可以用来生成随机数,随机点或者旋转

Random类的成员变量:

Mathf类

简述:提供了常用的数学运算

Mathf类的变量

Mathf类的常用方法

Coroutine协同程序

简述:也称为同程序或者协程,协同程序可以喝主程序并行运行,和多线程有些类似但是在任意指定时刻只会有一个协同程序在运行,别的程序则会挂起。协同程序可以用来实现让一段程序等待一段儿时间后继续运行的效果。

例如:执行步骤1 ,等待3秒;执行步骤2,等待某个条件为true;执行不会走。。。

Unity里和协同程序有关的函数有:

注意:在c#中,协同函数的返回类型必须为IEnumerator,yield要用yieldreturn来替代,并且启动协同程序右StartCoroutine函数

例程:

测试结果为:

2019-04-01 14:50:31 weixin_43746343 阅读数 105
  • DOTween插件API详解及案例实现

     游戏制作中少不了一些简单又有趣的动画。要完成这些动画,使用插件是最快最有效的解决方案了,DOTween插件功能基本涵盖了常用动画效果的所有需求。本课程详细讲解了DOTween插件的API使用及示例动画效果的实现,并附上API使用文档,方便以后查看。作为游戏开发中常用插件之一,DOTween以高效、简洁的优势被越来越多的Unity开发人员青睐。想要全面了解这款插件的小伙伴们,速速学起来吧!   Unity版本:2018.2.17   寄语:学会珍惜每个今天,才能拥有无悔的明天。

    960 人正在学习 去看看 张增会

本文章内容来自于擅码网Unity3D视频教程:http://www.mkcode.net/


Unity3D常用API之工具类(Screen,Time,Mathf)

代码:
public class ToolsClass : MonoBehaviour
{
    private float num = 0;

    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        // 屏幕类
        if (Input.GetKeyDown(KeyCode.UpArrow))
        {
            Debug.Log("屏幕高度:" + Screen.height);
            Debug.Log("屏幕宽度:" + Screen.width);
        }

        // 时间类
        //Debug.Log(Time.time); // 游戏运行时间
        //Debug.Log(Time.deltaTime); // 渲染一帧的时间
        //Time.timeScale = 1; // 时间缩放,控制游戏速度 暂停:0

        // 数学类
        if (Input.GetKeyDown(KeyCode.DownArrow))
        {
            Debug.Log(Mathf.Abs(-7)); // 求绝对值
            Debug.Log(Mathf.Max(-7,-3)); // 求最大值
            Debug.Log(Mathf.Min(-7, -3)); // 求最小值
            Debug.Log(Mathf.Round(2.6f)); // 四舍五入

            Debug.Log(Mathf.Lerp(10, 10, 0.7f)); // 差值运算 目的“平滑过渡”
        }

        // 一个数从0,插值到10
        num = Mathf.Lerp(num, 10, Time.deltaTime);
        Debug.Log(num);
    }
}
图:

2017-09-03 20:36:33 MacYosef 阅读数 863
  • DOTween插件API详解及案例实现

     游戏制作中少不了一些简单又有趣的动画。要完成这些动画,使用插件是最快最有效的解决方案了,DOTween插件功能基本涵盖了常用动画效果的所有需求。本课程详细讲解了DOTween插件的API使用及示例动画效果的实现,并附上API使用文档,方便以后查看。作为游戏开发中常用插件之一,DOTween以高效、简洁的优势被越来越多的Unity开发人员青睐。想要全面了解这款插件的小伙伴们,速速学起来吧!   Unity版本:2018.2.17   寄语:学会珍惜每个今天,才能拥有无悔的明天。

    960 人正在学习 去看看 张增会

记录并解析unity中经常用到的API

1.Camera

1.pixelRect

pixelRect属性:摄像机渲染区间
此属性用于设置camera被渲染到屏幕中间的坐标位置。pixelRect属性与rect功能类似,不同的是pixelRect以实际像素大小来设置显示视口的位置,而rect以单位化方式设置显示视口的位置。
例设置camera.pixelRect (x0,y0,w,h), x0为视口右移的像素大小,y0为视口上移的像素大小,w为camera.pixelWidth,h的值为camera.pixelHeight.

2.Mathf

1.PingPong

public static float PingPong(float t,float length)
此方法用于模拟乒乓球的往复运动。设f = Mathf.PingPong (t, h),其中f 、t、h均为 float值类型。
(1)若h>0,则

  f=|t| % h,        当 |t| % 2h <= h时
  f=h - |t| % h,    当 |t| % 2h > h时

(1)若h<0,则

  f=2h + |t| % |2h|,        当| t | % |2h| <= h时
  f= - |t| % |2h|,    当| t | % |2h| > h时

要想让物体进行PingPong运动, t 必须是一个不断改变的值 ,常用Time.time 来当作 t 值。f 会从 0 开始变化到 h ,然后再从 h 变化到0.

3.Rigidbody

1.SweepTest

语法:

public bool SweepTest(Vector3 direction, out RaycastHit hitInfo, float maxDistance = Mathf.Infinity, QueryTriggerInteraction queryTriggerInteraction = QueryTriggerInteraction.UseGlobal); 
参数 作用
direction 刚体扫过的方向
hitInfo 如果返回true,hitInfo将包含更多关于被击中位置碰撞体的信息
maxDistance 扫到的长度,默认为无穷大

2.WakeUp

语法:public void WakeUp( );
功能:此方法用于将刚体从休眠状态唤醒。要将刚体从休眠状态唤醒,除了调用此方法以外,在以下四种情况发生时,刚体会被自动唤醒:

  • 其他刚体与休眠中的刚体发生了碰撞
  • 使用关节连接的其他刚体发生了移动
  • 刚体的属性发生了改变
  • 给休眠中的刚体施加了一个外力

3.OnTriggerXXX和OnCollisionXXX

设现有A、B两个物体,且A物体正向B移动,B物体保持静止状态,如图所示:

这里写图片描述

详解:

  • 若A中无Rigidbody组件,则B中无论是否含有Rigidbody组件,A都将穿过B物体,并且A和B脚本中的OnTriggerXXX和OnCollisionXXX方法都不会调用。

  • 若A中含有Rigidbody组件,则B中无论是否含有Rigidbody组件,只要B中含有Collider类组件,A和B脚本中的OnTriggerXXX或OnCollisionXXX方法就会被调用。到底调用哪一种要看A和B物体中的Collider类组件中的IsTrigger是否被选中。总之,要激活OnTriggerXXX或OnCollisionXXX方法必须使移动的物体中含有Rigidbody组件

  • 若A中含有Rigidbody组件,B中含有Collider类组件,当A和B物体中的Collider类组件的IsTrigger都没有选中时,A和B脚本中(两个物体)的OnCollisionXXX类的方法就会被调用

  • 若A中含有Rigidbody组件,B中含有Collider类组件,当A和B物体中的Collider类组件的IsTrigger至少有一个被选中时,A和B脚本中(两个物体)的OnTriggerXXX静态方法会被调用

4.Transform

1.localPosition

public Vector3 localPosition { get; set; }

此属性用于设置或返回GameObject在局部坐标系中的位置,若无父级对象则和属性Transform.position返回值相同。

transform.localPosition的值受父级对象lossyScale的影响,当transform.localPosition的值增加1时,transform.position的值的增量不一定是1,而是在相对父级坐标系中增加了父级的lossyScale倍大小的值。例如物体cube2的父级是cube1,cube1的父级是cube0,cube1的localScale为Vector3(c1x,c1y,c1z),cube0的localScale为Vector3(c0x,c0y,c0z),假设cube0和cube1都没有发生旋转,则GameObject对象在世界坐标系中的位置为:
transform.position.x = cube0.localPosition.x+cube1.localPosition.x*c0x+transform.localPosition.x*c1x*c0x;
transform.position.y和transform.position.z与此相同。
当物体cube2的局部坐标值localPosition增加Vector3(tx,ty,tz)时,其世界坐标值position的增加值分别为:
_x=tx*c1x*c0x;
_y=ty*c1y*c0y;
_z=tz*c1z*c0z;

5.Vector3

1.RotateTowards

基本语法:public static Vector3 RotateTowards( Vector3 current, Vector3 target, float maxRadiansDelta, float maxMagnitudeDelta);
其中参数current为起始点坐标,参数target为目标点坐标,参数maxRadiansDelta为角度旋转系数,参数maxMagnitudeDelta为模长系数。

功能说明:
此方法用于返回从参数current到target的球形旋转插值向量,此方法可控制插值向量的角度和模长。例如,设有Vector3实例A、B和C,有float类型数值R和L,向量A和B的夹角的弧度为e,则执行以下程序代码后
C=Vector3.RotateTowards(A,B,R,L);

  • 当R∈[0,e]时,向量C和A的弧度为R,即当R从0增加到e时,向量C与A的角度也会线性增加到e。向量C的模长为向量A的模长加上L的值,即|C|=|A|+L.
  • 当R<0时,向量C会沿着A到B的反向量旋转。
  • 当R>e时,参数R以e来计算角度,即R大于e时C与B的方向相同。
  • 总之,R值决定了向量C的方向,而L影响了C的模长,无论L取值多少,当R>e时向量C与B的方向总是相同的。
  • 向量A、B和C在同一平面上。

2.Slerp

基本语法:public static Vector3 Slerp(Vector3 from, Vector3 to, float t);
其中参数from为插值起始点坐标,参数to为插值结束点坐标,参数t为插值系数。
功能说明:此方法用于返回从参数from点到参数to点的球形插值向量。例如,设现有Vector3实例A和B,A ( ax,ay,az), B( bx,by,bz) A和B的夹角为e,则执行如下代码后
Vector C = Vector3.Slerp(from,to,t);

  • 当t<=0时,向量C=A;
  • 当t>=1时,向量C=B;
  • 当t从0增加到1时,向量C会从起始点A绕着A*B(即向量A和B的叉乘)的方向匀速移动到向量B,此处的匀速时指角度旋转的匀速,即向量C与B的夹角k=e*(1-t),这样便可以确定向量C的方向。而向量C的模长计算公式则为:
    |C|=ax2+ay2+az2+(bx2+by2+bz2ax2+ay2az2)t
  • 当向量A和B中的某个分量的值都为0时,比如它们的y轴分量都为0,即ay=by=0时,则A将绕着y轴在xy平面匀速旋转向B移动,并且在移动过程中C.y的值始终为0.

Unity 3D - 常用API

阅读数 679

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