[U3D Learning Note] Unity C# Survival Guide (10) -- Static Types

Static Types

Static Types: use the keyword static. Static information can be thought of as stuck in the program’s memory for the life of the program.static类型保证了这个物体的信息在整个游戏的进行中不会销毁,即使物体本身已经被销毁。信息通过相关类获取的, 和脚本依附的物体无关

public class Score : MonoBehaviour
{
    public static int score;
}

public class StaticTest : MonoBehaviour
{
    private Score _score;
    // Start is called before the first frame update
    void Start()
    {
        //_score = GameObject.Find("ScoreKeeper").GetComponent<Score>(); // Do not use this
    }

    // Update is called once per frame
    void Update()
    {
        if(Input.GetKeyDown(KeyCode.Space)){
           // _score.score += 10; // Do not use this
           Score.score += 10; //correct way
        }   
    }
}

static允许我们在类的层次上取获取信息,因为这一类型的数据是无限期存储在记忆体中,我们不需要通过一个实例来获取信息
另外一个要注意的是,在static函数中使用的变量也要是static的

KEY:(in part 2 of this chapter)

  • 在游戏界面上显示文本等:
    • 创建画布:Hierarchy右键->UI->Canvas
    • 创建文本:Hierarchy右键->UI->Text (图片什么的同理
  • 游戏背景:在Main CameraClear Flag进行设置 默认是sky box 想要纯颜色就切换成Solid Color
  • OnEnable() / OnDisable():Make GameObject become inabled or disabled(when u destory a GameObject, it’s not longer enabled

讲一下part2这边的代码吧 这组代码实现的功能很简单 生成物体并在一定时间内销毁 在界面显示当前存在的物体数量 创建两个GameObject Spawn_Manager和UI_Manager分别用于生成enemy和UI界面设置 以及生成对象预制件Enemy

/* SpawnManager.cs*/
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SpawnManager : MonoBehaviour
{
    public GameObject enemyPrefab;
    public static int enemyCount; // will be used in whole game    
    // Start is called before the first frame update
    void Start()
    {        
    }
    // Update is called once per frame
    void Update()
    {
        //instantiate
        if(Input.GetKeyDown(KeyCode.Space)){
            Instantiate(enemyPrefab);
        }
    }
}

/* UIManager.cs*/
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI; // this package reference to UI
public class UIManager : MonoBehaviour
{
    // Start is called before the first frame update
    public Text activateEnemiesText; // get text info 

    public void UpdateEnemyCount(){
        activateEnemiesText.text = "Active Enemies: " + SpawnManager.enemyCount;
    }
}

/* Enemy.cs */
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

// when enemy instantiate, EnemyCount incre; if destory, decre
public class Enemy : MonoBehaviour
{
    private UIManager _ui;
    public void OnEnable() 
    {
        SpawnManager.enemyCount++;
        _ui = GameObject.Find("UI_Manager").GetComponent<UIManager>(); //Script is also a component
        _ui.UpdateEnemyCount(); // when the enemyCount change, call this function to update the number on the screen immediately
        Die();
    }
    public void OnDisable()
    {
        // when this object destory, it become Disabled status
        SpawnManager.enemyCount--;
        _ui.UpdateEnemyCount();
    }
    
    void Die(){
        Destroy(this.gameObject, Random.Range(2, 6)); //destory the obj after 2-6s(random)
    } 
}

Instance Members vs. Static Members

Static members live for the life of the program, whereas instance members have instances of themselves. When we create a custom item class, we’re creating instances of those items. When u have a static variable within a traditional class, that variable is shared amongst all these instance.

举个栗子

public class InsItem{
    public string name;
    public int itemID;
    public static int itemCount;
    
	public InsItem(){
        itemCount++; // when a instance create, itemCount++
    }
}

public class InstanceTest : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        InsItem sword = new InsItem();
        InsItem bread = new InsItem();
        Debug.Log(InsItem.itemCount); //2
    }
    // Update is called once per frame
    void Update()
    {        
    }
}

对于sword和bread这两个实例, 我们可以很容易通过sword.name, sword.itemID获取name和itemID属性并进行改变,但是我们却无法通过进行sword.itemCount操作来获取。因为这些实例他们共享itemCount这一变量。itemCount是在整个程序中无限期存在的,无论是否有一个InsItem实例。如果要获取这个静态变量,我们只能通过InsItem.itemCount来获取。
Static members are shared across all the instance, whereas instance members are created as copies. 以这个例子来说, nameitemID在一个InsItem 实例被创建时就被拷贝一份,而itemCount是一个共享数据。
[场景]:多人游戏(multiplayer games)的在线人数统计, 当玩家上线时然后会显示当前世界有多少人在线。把上面那个InsItem类改一改叫做Player的类好了(其实没差 , 每当玩家上线时就创建一个Player实例然后人数增加。 (提问:玩家下线时,当前世界人数如何减少\

Utility Helper Classes

Utility Classes are basically helper methods that you have created so that u can ideally streamline your development process.

一般情况下 你的UtilityClass不需要继承MonoBehaviour 它将会是一个static class并存储一堆static methods方便调用

KEY of Utility Class:

  • 不继承MonoBehaviour
  • 里面的变量和方法都是static的(因为他是static class

来看一个代码 先把涉及到的函数做个解释

  • GameObject.CreatePrimitive(PrimitiveType): 创建一个原始的GameObject(包含了mesh renderer和collider),括号内是这个GObj的类型,比如cube,cylinder之类的
    在调用这些函数时直接在类的层次上进行调用 就不需要再创一个GameObject来存储这些操作
public static class UtilityClass
{
    public static void CreateObject()
    {
        // create a new primitive cube
        GameObject.CreatePrimitive(PrimitiveType.Cube);
    }

    public static void SetPositionToZero(GameObject obj)
    {
        // change position of obj
        obj.transform.position = Vector3.zero;
    }
    
}

Initializing Static Members with a Static Constructor

比如说我们现在有一个类,里面有普通的变量也有静态变量。当我们要初始化这个类里面的值时,我们通常就是通过构造函数来实现,来初始化一个实例。那么对于static变量,我们可以用static constructor。这是为了保证当我们在创建这个类的实例前,我们的这个静态变量已经被初始化(因为这是一个在实例中共享的变量)。

public class Employee
{
    public string first, last;
    public int employeeID;
    public int salary;
    public static string company;

    public Employee(){
        Debug.Log("Initialize Instance Members");
    }

    // to make sure "company" is assigned before create a employee
    static Employee(){
        company = "RinMZK";
        Debug.Log("Initialize Static Members");
    }
}

public class TrackEmployee : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        Employee em1 = new Employee();
        Employee em2 = new Employee();
    }

    // Update is called once per frame
    void Update()
    {   
    }
}

我们可以来看看它的执行顺序
在这里插入图片描述
很明显是先执行static constructor将静态变量初始化然后再创建实例。我们可以注意到的是,static constructor只执行一次,无论创建了多少实例。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值