一、什么是协程、它是如何执行的

如果执行的是一个普通方法,那么会等这个普通方法执行完,然后继续向下执行
如果调用的是一个协程方法,那么调用完协程方法后,不会等这个方法执行完,就继续向下执行了。

public class API08Coroutine : MonoBehaviour
{
    public GameObject cube;
 void Start ()
    {       
        print("ha");
        //ChangeColor();
        StartCoroutine(ChangeColor());
        //协程方法开启后,会继续运行下面的代码,不会等协程方法运行结束才继续执行
        print("hahaha");
 }
    //Coroutine
    //1.返回值IEnumerator
    //2.返回参数的时候使用yield return
    //3.协程方法的调用StartCoroutine(method());
    IEnumerator ChangeColor()
    {
        print("haColor");
        cube.GetComponent<MeshRenderer>().material.color = Color.blue;
        print("hahaColor");
        yield return null;
    }
}

二、使用Coroutine实现颜色动画渐变

public class API08Coroutine : MonoBehaviour
{
    public GameObject cube;
 void Start ()
    {       
        //print("ha");
        ChangeColor();
        //StartCoroutine(ChangeColor());
        协程方法开启后,会继续运行下面的代码,不会等协程方法运行结束才继续执行
        //print("hahaha");
 }
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            StartCoroutine(Fade());
        }
    }
    //实现渐变改变颜色
    IEnumerator Fade()
    {
        for (; ; )//这是个死循环
        {
            //1.cube.GetComponent<MeshRenderer>().material.color = new Color(i,i,i,i);
            Color color = cube.GetComponent<MeshRenderer>().material.color;
            Color newColor = Color.Lerp(color,Color.red,0.02f);
            cube.GetComponent<MeshRenderer>().material.color = newColor;
            yield return new WaitForSeconds(0.02f);
            if (Mathf.Abs(Color.red.g-newColor.g)<=0.01f)
            {
                break;
            }
        }
    }
    //Coroutine
    //1.返回值IEnumerator
    //2.返回参数的时候使用yield return
    //3.协程方法的调用StartCoroutine(method());
    IEnumerator ChangeColor()
    {
        print("haColor");
        yield return new WaitForSeconds(3);//暂停三秒在执行后面的代码
        cube.GetComponent<MeshRenderer>().material.color = Color.blue;
        print("hahaColor");
        yield return null;
    }
}

三、Coroutine协程的开启和关闭

public class API08Coroutine : MonoBehaviour
{
    public GameObject cube;
 void Start ()
    {       
        //print("ha");
        ChangeColor();
        //StartCoroutine(ChangeColor());
        协程方法开启后,会继续运行下面的代码,不会等协程方法运行结束才继续执行
        //print("hahaha");
 }
    private IEnumerator ie;
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            //第一种关闭方式
            //ie = Fade();
            //StartCoroutine(ie);
            //第二种关闭方式,开启跟关闭是对应着的
            StartCoroutine("Fade");
        }
        if (Input.GetKeyDown(KeyCode.S))
        {
            //StopCoroutine(ie);
            StopCoroutine("Fade");
        }
    }
    //实现渐变改变颜色
    IEnumerator Fade()
    {
        for (; ; )//这是个死循环
        {
            //1.cube.GetComponent<MeshRenderer>().material.color = new Color(i,i,i,i);
            Color color = cube.GetComponent<MeshRenderer>().material.color;
            Color newColor = Color.Lerp(color,Color.red,0.02f);
            cube.GetComponent<MeshRenderer>().material.color = newColor;
            yield return new WaitForSeconds(0.02f);
            if (Mathf.Abs(Color.red.g-newColor.g)<=0.01f)
            {
                break;
            }
        }
    }
    //Coroutine
    //1.返回值IEnumerator
    //2.返回参数的时候使用yield return
    //3.协程方法的调用StartCoroutine(method());
    IEnumerator ChangeColor()
    {
        print("haColor");
        yield return new WaitForSeconds(3);//暂停三秒在执行后面的代码
        cube.GetComponent<MeshRenderer>().material.color = Color.blue;
        print("hahaColor");
        yield return null;
    }
}

四、跟鼠标相关事件函数OnMouseXXX讲解

public class API09OnMouseEvent : MonoBehaviour
{
    void OnMouseDown()
    {
        print("Down"+gameObject);
    }
    void OnMouseUp()
    {
        print("UP" + gameObject);
    }
    void OnMouseDrag()
    {
        print("Drag" + gameObject);
    }
    void OnMouseEnter()
    {
        print("Enter" + gameObject);
    }
    void OnMouseExit()
    {
        print("Exit" + gameObject);
    }
    void OnMouseOver()
    {
        print("Over" + gameObject);
    }
    void OnMouseUpAsButton()
    {
        print("Button");
    }
}

五、Mthf里面的静态常量

public class API10Mthf : MonoBehaviour
{
 void Start ()
    {
        //度数转弧度
        print(Mathf.Deg2Rad);
        //弧度转度数
        print(Mathf.Rad2Deg);
        //无限大的数
        print(Mathf.Infinity);
        //无限小的数
        print(Mathf.NegativeInfinity);
        //π的值
        print(Mathf.PI);
        //大于0的小数
        print(Mathf.Epsilon);
    }
 void Update ()
    {
    }
}

六、Mathf中的Clamp限定方法

Abs去绝对值
Ceil向上取整(返回的是Float)
CeilToInt向上取整(返回的是Int类型的)
Clamp把一个值限定在一个范围之内
Clamp01把值限定在0~1之间

public class API10Mthf : MonoBehaviour
{
    public Transform cube;
 void Start ()
    {
        度数转弧度
        //print(Mathf.Deg2Rad);
        弧度转度数
        //print(Mathf.Rad2Deg);
        无限大的数
        //print(Mathf.Infinity);
        无限小的数
        //print(Mathf.NegativeInfinity);
        π的值
        //print(Mathf.PI);
        大于0的小数
        //print(Mathf.Epsilon);
 }
 void Update ()
    {
        //把Time.time的值限定在1到3之间,如果比1小,就返回1,比3大就返回3,如果在1到3之间就返回它本身的值
        //cube.position = new Vector3(Mathf.Clamp(Time.time,1.0f,3.0f),0,0);
        Debug.Log(Mathf.Clamp(Time.time, 1.0f, 3.0f));
 }
    //计算伤害时用
    private int hp = 100;
    void TakeDamage()
    {
        hp -= 9;
        //if (hp<0)
        //    hp = 0;
        //简单写法
        hp = Mathf.Clamp(hp,0,100);
    }
}

七、Mathf中的常用方法

ClosestPowerOfTwo取得离2的次方的值最近的数,2,4,8,16,32
DetlaAngle(计算出两个角度之间最短的距离)
Exp(e的多少次方)
Floor向下取整(float类型 10.2取10,-10.2取-11)
FloorToInt向下取整(Int类型)
Lerp
LerpAngle
Max(取得最大值)
Min(取得最小值)
Pow(f,p)(里面有两个值,取得f的p次方,float f,float p)
Sqrt(取得参数的平方根)

public class API10Mthf : MonoBehaviour
{
    public Transform cube;
 void Start ()
    {
        度数转弧度
        //print(Mathf.Deg2Rad);
        弧度转度数
        //print(Mathf.Rad2Deg);
        无限大的数
        //print(Mathf.Infinity);
        无限小的数
        //print(Mathf.NegativeInfinity);
        π的值
        //print(Mathf.PI);
        大于0的小数
        //print(Mathf.Epsilon);
        //向下取整
        //Debug.Log(Mathf.Floor(10.0f));
        //Debug.Log(Mathf.Floor(10.2f));
        //Debug.Log(Mathf.Floor(10.7f));
        //Debug.Log(Mathf.Floor(-10.0f));
        //Debug.Log(Mathf.Floor(-10.2f));
        //Debug.Log(Mathf.Floor(-10.7f));


        //取得离2的次方的值最近的数,2,4,8,16,32
        print(Mathf.ClosestPowerOfTwo(2));//4
        print(Mathf.ClosestPowerOfTwo(3));//8
        print(Mathf.ClosestPowerOfTwo(4));//8
        print(Mathf.ClosestPowerOfTwo(5));//8
        print(Mathf.ClosestPowerOfTwo(6));//8
        print(Mathf.ClosestPowerOfTwo(30));//8
        print(Mathf.Max(1,2));//2
        print(Mathf.Max(1,2,5,3,10));//10
        print(Mathf.Min(1, 2));//1
        print(Mathf.Min(1,2,5,3,10));//1
        print(Mathf.Pow(4,3));//64
        print(Mathf.Sqrt(3));//1.73
    }
 void Update ()
    {
        //把Time.time的值限定在1到3之间,如果比1小,就返回1,比3大就返回3,如果在1到3之间就返回它本身的值
        //cube.position = new Vector3(Mathf.Clamp(Time.time,1.0f,3.0f),0,0);
        //Debug.Log(Mathf.Clamp(Time.time, 1.0f, 3.0f));
 }
    //计算伤害时用
    private int hp = 100;
    void TakeDamage()
    {
        hp -= 9;
        //if (hp<0)
        //    hp = 0;
        //简单写法
        hp = Mathf.Clamp(hp,0,100);
    }
}

八、关于游戏开发中的插值运算

Lerp(a,b,t)t是0~1的比例,假设a=9,b=20

unity中类似ifram_取整

public class API10Mthf : MonoBehaviour
{
    public Transform cube;
    public int a = 8;
    public int b = 20;
    public float t = 0;//必须是float类型
    void Start ()
    {
        度数转弧度
        //print(Mathf.Deg2Rad);
        弧度转度数
        //print(Mathf.Rad2Deg);
        无限大的数
        //print(Mathf.Infinity);
        无限小的数
        //print(Mathf.NegativeInfinity);
        π的值
        //print(Mathf.PI);
        大于0的小数
        //print(Mathf.Epsilon);
        //向下取整
        //Debug.Log(Mathf.Floor(10.0f));
        //Debug.Log(Mathf.Floor(10.2f));
        //Debug.Log(Mathf.Floor(10.7f));
        //Debug.Log(Mathf.Floor(-10.0f));
        //Debug.Log(Mathf.Floor(-10.2f));
        //Debug.Log(Mathf.Floor(-10.7f));
        
        //取得离2的次方的值最近的数,2,4,8,16,32
        //print(Mathf.ClosestPowerOfTwo(2));//4
        //print(Mathf.ClosestPowerOfTwo(3));//8
        //print(Mathf.ClosestPowerOfTwo(4));//8
        //print(Mathf.ClosestPowerOfTwo(5));//8
        //print(Mathf.ClosestPowerOfTwo(6));//8
        //print(Mathf.ClosestPowerOfTwo(30));//8
        //print(Mathf.Max(1,2));//2
        //print(Mathf.Max(1,2,5,3,10));//10
        //print(Mathf.Min(1, 2));//1
        //print(Mathf.Min(1,2,5,3,10));//1
        //print(Mathf.Pow(4,3));//64
        //print(Mathf.Sqrt(3));//1.73


        cube.position = new Vector3(0,0,0);
    }
 void Update ()
    {
        //把Time.time的值限定在1到3之间,如果比1小,就返回1,比3大就返回3,如果在1到3之间就返回它本身的值
        //cube.position = new Vector3(Mathf.Clamp(Time.time,1.0f,3.0f),0,0);
        //Debug.Log(Mathf.Clamp(Time.time, 1.0f, 3.0f));


        //插值
        //print(Mathf.Lerp(a,b,t));
        float c = cube.position.x;
        //float newX= Mathf.Lerp(c,10,0.1f);
        //一般不是自己定义,一般是用时间
        //嫌慢的话可以乘以速度Time.deltaTime*Speed
        float newX = Mathf.Lerp(c,10,Time.deltaTime);
        cube.position = new Vector3(newX ,0,0);
 }
    //计算伤害时用
    private int hp = 100;
    void TakeDamage()
    {
        hp -= 9;
        //if (hp<0)
        //    hp = 0;
        //简单写法
        hp = Mathf.Clamp(hp,0,100);
    }
}