2016-02-17 15:10:16 u014261855 阅读数 724

        任何软件都是有生命周期的,unity3d项目也不例外,由于我现在从事手游开发,就分析一下unity3d手游项目的生命周期,其实unity3d项目由各个组件和控制组件的脚本组成,脚本就是项目的脉络。由于unity开发项目封装性非常优越,代码对项目的意义变得不那么明显。做过其它引擎开发(比如cocos2d,MFC)的可以更清楚这一点。其实一个项目还是由代码和资源完成的,二资源是不变的,既然如此,项目可以说是有代码构成的,那么,项目的生命周期就是代码的生命周期,在unity中就是脚本的生命周期

         看一下基本的脚本生命周期函数,这些现有的资料都很详细,也都很容易理解(只要继承与MonoBehaviour的类都享有所有的生命周期函数)。


分析一下App的生命周期函数,也都是MonoBehaviour的成员函数,这些函数我在网上没有找到总结,就自己看着API的介绍总结一下:

(注意API中这些周期函数都有一句解释,sent toall game objects when…..,就是说每当程序触发这些事件的时候,所有的组件都会收到消息,并调用这个周期函数。这就可以很方便的管理我们的应用,比如当切换焦点的时候,在OnApplicationFocus中写一个调用暂停的对话框,下次运行的时候就可以等用户确定了再开始应用。)

1.      OnApplicationFocus()每当屏幕焦点切换进入或者切换出去当前App时调用。平时手机点一下Home键切换到主屏幕,就失去了焦点,切换回来,就得到了焦点。

2.      OnApplicationPause()暂停的时候调用(我们平时暂停游戏用Time.timeScale= 0),然后再添加暂停处理方式,不知道这玩意有什么卵用。我用编译器暂停也不调用它,好忧伤。

3.      OnApplicationQuit()退出时调用(它和脚本的OnDestroy不同,脚本被被删除或者组件被删除的时候都会调用OnDestroy,但是只有程序退出的时候才会调用这个函数)

目前unity3d提供APP周期函数就这三个,还比较简单吧。

 

 

2015-08-14 10:23:25 u010024824 阅读数 3069

Null Reference Exception : Object reference not set to an instance of an object.

异常:空引用,对象的引用未设置到对象的实例。

出现该异常的位置:

可能是在调用组件时该组件还未实例化或未存储地址指针,需要查看是否将组件位置拽入代码公布的字段;还有注意Unity3D的生命周期,调整代码的执行顺序。




(若有错误和不足之处,还望指正,谢谢!)

2014-11-10 23:47:21 zky1347888 阅读数 1500

组件绑定脚本请看:http://blog.csdn.net/tutuboke/article/details/40894433

绑定后,先写脚本,代码如下:

using UnityEngine;
using System.Collections;

public class Test1 : MonoBehaviour {
	//变量设置为public 可以再unity3D的编辑器中调节 初值及运行时可能查到值得时时变化
	public int i;
	public int j;
	public int k;
	//唤醒一个脚本 第一个执行 执行一次
	void Awake(){
		Debug.Log ("Awake");
	}
	// 开始  执行一次
	void Start () {
		Debug.Log("Start");
	}
	//绘制界面的  每帧都会调用
	void OnGUI()
	{
		if (k==0)
			Debug.Log ("onGui");
		k = 1;
	}
	// 每帧都执行update
	void Update () {
		if (i == 0)
		{
			Debug.Log("Update");
		}
	}
	//update函数之后调用 每帧都会调用
	void LateUpdate(){
		if (i == 0)
		{
			Debug.Log("LateUpdate");
			i = 1;
		}
	}
	//定时调用
	//Edit->preject setting ->Time -> (Inspector监测视图)Fixed Timestep 设置刷新时间
	void FixedUpdate(){
		if (j==0)
		 Debug.Log("FixedUpdate");
		j = 1;
	}
	//绑定的组件被删除调用
	void OnDestroy()
	{
		Debug.Log("OnDestroy");
	}
}

运行u3d ui编辑器,在UI编辑器的左下角查看运行信息及log 出现效果:




2019-12-10 00:13:56 qq_30087879 阅读数 14

脚本的生命周期

代码

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class NewBehaviourScript : MonoBehaviour
{
    // 只会执行一次 无论脚本是否激活,都会被执行。前提是脚本所在对象必须是激活状态
    private void Awake()
    {
        Debug.Log("Awake");
    }
    // 脚本激活或者脚本所依附的对象被激活时执行
    private void OnEnable()
    {
        Debug.Log("OnEnable");
    }
    // 只会执行一次 且只能 在脚本处于激活状态或者脚本第一次被激活时执行
    // Start is called before the first frame update
    void Start()
    {
        Debug.Log("Start");
    }
    // 固定帧率刷新 不受游戏帧率影响,默认帧间隔为0.02s,可以在projectseting-Time-fixed timestep中设置
    private void FixedUpdate()
    {
        Debug.Log("FixedUpdate");
    }

    // Update is called once per frame
    void Update()
    {
        Debug.Log("Update");
    }
    // 在update之后执行
    private void LateUpdate()
    {
        Debug.Log("LateUpdate");
    }
    // 脚本取消激活时或者脚本所依附的对象取消激活时执行
    private void OnDisable()
    {
        Debug.Log("OnDisable");
    }
    // 脚本所依附的对象被销毁时执行
    private void OnDestroy()
    {
        Debug.Log("OnDestroy");
    }
}

u3d主线程框架运行图
在这里插入图片描述

代码分析

说明一点脚本必须继承monobehaviour ,脚本才能作为组件挂在对象上并且具有这些生命周期函数。
在代码的注释中已经有详细的介绍,这里说明一下FixedUpdate ,他是固定帧间隔的函数,执行顺序在update之前,他的帧间隔默认是0.02s,可以在untiy中修改,如下图
在这里插入图片描述
Update会受到渲染物体的影响帧率不固定的
LateUpdate 在Update之后执行,同样是不固定帧率的刷新,收到渲染物体影响。

帧率设置

untiy中设置fps刷新帧率
可以在代码中进行设置Application.targetFrameRate 用来设置帧率,可以在脚本的Awake中进行设置

  1. Application.targetFrameRate=-1:表示以最大帧率执行,最快速度运行
  2. Application.targetFrameRate=30:设置帧率为30

Application.targetFrameRate设置生效有以下前提取消垂直同步如下图

在这里插入图片描述
只有这样才能使代码中的设置生效
设置垂直同步为1,如图表示以60帧运行
在这里插入图片描述
设置垂直同步为2 ,如图表示以30帧运行在这里插入图片描述

2017-09-25 16:54:59 qq_28112287 阅读数 312

直接上代码:
**生命游戏
生命游戏(game of life)为1970年由英国数学家J. H. Conway所提出,某一细胞的邻居包括上、下、左、右、左上、左下、右上与右下相邻之细胞。
规则
生命游戏中,对于任意细胞,规则如下:
每个细胞有两种状态-存活或死亡,每个细胞与以自身为中心的周围八格细胞产生互动。(如图,黑色为存活,白色为死亡)
当前细胞为死亡状态时,当周围有3个存活细胞时,该细胞变成存活状态。 (模拟繁殖)
当前细胞为存活状态时,当周围低于2个(不包含2个)存活细胞时, 该细胞变成死亡状态。(模拟人口稀少)
当前细胞为存活状态时,当周围有2个或3个存活细胞时, 该细胞保持原样。
当前细胞为存活状态时,当周围有3个以上的存活细胞时,该细胞变成死亡状态。(模拟过度拥挤)**
`

public int mapSize = 100;//图的大小
private int[,] cellDataMap;//数据图 0=死亡 1=存活
private GameObject[,] cellObjeMap;//实物图

public GameObject cellPrefab;//细胞的预制体
public Transform createPosition;//创建图的起始点

float timer;
public float timeRate=1f;//时间间隔

private void Start()
{
    cellDataMap = new int[mapSize, mapSize];
    cellObjeMap = new GameObject[mapSize, mapSize];

    timer = 0;

    CreateMap();
}
private void Update()
{
    timer += Time.deltaTime;
    if (timer > timeRate)
    {
        UpdateMap();
        timer = 0;
    }
}




/// <summary>
/// 创建图
/// </summary>
private void CreateMap()
{
    for (int i = 0; i < mapSize; i++)
    {
        for (int j = 0; j < mapSize; j++)
        {
            cellDataMap[i, j] = Random.Range(0, 2);
            if (cellDataMap[i, j] == 1)
            {
                cellObjeMap[i, j] = Instantiate(cellPrefab, createPosition.position + new Vector3(j * 1, 0, i * 1), Quaternion.identity);
            }
        }
    }
}
/// <summary>
/// 更新图
/// </summary>
private void UpdateMap()
{
    int[,] tempMap = new int[mapSize, mapSize];
    tempMap = (int[,])cellDataMap.Clone();//克隆函数

    for (int i = 0; i < mapSize; i++)
    {
        for (int j = 0; j < mapSize; j++)
        {
            //当前细胞为死亡状态时,当周围有3个存活细胞时,该细胞变成存活状态。 (模拟繁殖)
            //当前细胞为存活状态时,当周围低于2个(不包含2个)存活细胞时, 该细胞变成死亡状态。(模拟人口稀少)
            //当前细胞为存活状态时,当周围有2个或3个存活细胞时, 该细胞保持原样。
            //当前细胞为存活状态时,当周围有3个以上的存活细胞时,该细胞变成死亡状态。(模拟过度拥挤)
            int number = GetCellNumberInPos(i, j);
            if (tempMap[i, j] == 1)//存活状态
            {

                if (number < 2 || number > 3)//人口稀少和拥挤
                {
                    tempMap[i, j] = 0;
                }
            }
            else if (tempMap[i, j] == 0)//死亡状态
            {
                if (number == 3)//繁殖
                {
                    tempMap[i, j] = 1;
                }
            }
        }
    }

    ShowMap(tempMap);
}
/// <summary>
/// 显示图
/// </summary>
private void ShowMap(int[,] tempMap)
{
    for (int i = 0; i < mapSize; i++)
    {
        for (int j = 0; j < mapSize; j++)
        {
            if (tempMap[i, j] != cellDataMap[i, j])
            {
                cellDataMap[i, j] = tempMap[i, j];
                if (tempMap[i, j] == 0)
                {
                    Destroy(cellObjeMap[i, j]);
                }
                else if (tempMap[i, j] == 1)
                {
                    cellObjeMap[i, j] = Instantiate(cellPrefab, createPosition.position + new Vector3(j * 1, 0, i * 1), Quaternion.identity);
                }
            }
        }
    }
}
/// <summary>
/// 返回周围的存活的细胞的数量
/// </summary>
/// <param name="pos_y"></param>
/// <param name="pos_x"></param>
/// <returns>存货的细胞的数量</returns>
private int GetCellNumberInPos(int pos_y, int pos_x)
{
    int number = 0;
    for (int i = -1; i <= 1; i++)
    {
        for (int j = -1; j <= 1; j++)
        {
            if (pos_y + i < 0 || pos_y + i >= mapSize || pos_x + j < 0 || pos_x + j >= mapSize) continue;//细胞边界默认死亡
            if (i == 0 && j == 0) continue;//细胞本体不带入运算
            if (cellDataMap[pos_y + i, pos_x + j] == 1)
            {
                number++;
            }
        }
    }
    return number;
}`
没有更多推荐了,返回首页