Unity模拟《切尔诺贝利》中的控制棒
↓<切尔诺贝利>的镜头, 控制棒在上下跳动, 核电站马上要炸了 (导致数几十万人在痛苦中死去)
↓用Unity模拟一下, 当然, 只是画面模拟, 没有内核
上代码:
using System.Collections.Generic;
using UnityEngine;public class Mgr : MonoBehaviour
{const int xNum = 50;const int zNum = 50;const float height = 1f;const float upSpeed = 1.5f;const float downSpeed = -5f;Dictionary<int, Transform> all;Dictionary<int, States> states;Dictionary<int, States> temp;[SerializeField]Transform prefab;Color white = new Color(0.8f, 0.8f, 0.8f);Color grey = new Color(0.7f, 0.7f, 0.7f);Color yellow = new Color(0.8f, 0.8f, 0.4f);Color red = new Color(0.8f, 0.4f, 0.4f);Color green = new Color(0.4f, 0.8f, 0.4f);Color blue = new Color(0.4f, 0.4f, 0.8f);enum States{Idle,Up,Down,}void Start(){all = new Dictionary<int, Transform>();states = new Dictionary<int, States>();temp = new Dictionary<int, States>();Vector3 pos = Vector3.zero;Material material;for (int x = 0; x < xNum; x++){for (int z = 0; z < zNum; z++){Transform transform = Instantiate<Transform>(prefab);float xOffset = Random.Range(-0.04f, 0.04f);float zOffset = Random.Range(-0.04f, 0.04f);pos.x = x + xOffset;pos.z = z + zOffset;transform.position = pos;int key = x * 100 + z;all.Add(key, transform);states.Add(key, States.Idle);material = transform.GetComponent<Renderer>().material;material.color = white;if (x % 4 == 0 && z % 4 == 0 || (x + 2) % 4 == 0 && (z + 2) % 4 == 0){material.color = grey;}//有概率颜色不变?int random = Random.Range(0, 100);if (random > 15){if (x % 8 == 0 && z % 8 == 0 || (x + 4) % 8 == 0 && (z + 4) % 8 == 0){material.color = yellow;}if ((x + 4) % 8 == 0 && z % 8 == 0 || x % 8 == 0 && (z + 4) % 8 == 0){material.color = red;}if ((x + 12) % 24 == 0 && z % 24 == 0 || x % 24 == 0 && (z + 12) % 24 == 0){material.color = green;}}}}for (int i = 0; i < 25; i++){int randomX = Random.Range(0, xNum);int randomY = Random.Range(0, zNum);int key = randomX * 100 + randomY;all[key].GetComponent<Renderer>().material.color = blue;}}void Update(){RandomMoving();}//随机上下运动void RandomMoving(){int num = Random.Range(0, 3);for (int i = 0; i < num; i++){int randomX = Random.Range(0, xNum);int randomY = Random.Range(0, zNum);int key = randomX * 100 + randomY;states[key] = States.Up;}foreach (int key in states.Keys){Transform transform = all[key];States state = states[key];if (state == States.Up){if (transform.position.y < height){Vector3 pos = transform.position;pos.y += upSpeed * Time.deltaTime;transform.position = pos;}else{//states[key] = States.Down;temp.Add(key, States.Down);}}else if (state == States.Down){if (transform.position.y > 0f){Vector3 pos = transform.position;pos.y += downSpeed * Time.deltaTime;transform.position = pos;}else{//states[key] = States.Idle;temp.Add(key, States.Idle);}}}//最后再赋值, 因为不能在遍历中赋值foreach (int key in temp.Keys){states[key] = temp[key];}temp.Clear();}
}
这里取巧了, 用的是 (x * 100 + z) 作为字典的键, 在C#7以后, 可以用元数组<int,int>作为键, Dictionary<<int, int>, Transform>
也可以用双层列表做索引: list[x][z]
ok, 就酱