Some useful tips that I find useful while learning Unity.
Disclaimer: These tips are not absolute. Some of them might be actually bad in some situations, in light of the fact that I am still struggling to learn unity right now.
public class SpinScript : MonoBehaviour
{
[Range(-100, 100)] public int speed = 0;
void Update ()
{
transform.Rotate(new Vector3(0, speed * Time.deltaTime, 0));
}
}
[ExecuteInEditMode]
public class ColorScript : MonoBehaviour
{
void Start()
{
renderer.sharedMaterial.color = Color.red;
}
}
[HideInInspector] public bool inMainMenu;
ScriptableObject:
using UnityEngine;
[CreateAssetMenu]
public class MyScriptableObject : ScriptableObject
{
public int SomeVariable;
void OnEnable() {
}
void OnDisable() {
}
void OnDestroy() {
}
}
ScriptableObject.CreateInstance<MyScriptableObject>();
Application:
- data tables
- ...
- SINGLE RESPONSIBILITY: A given class should be, ideally, responsible for just one task.
- ABSTRACTION: see next rule
- MODULARIZATION
eg: IDamageable, IInventory
Also consider Invoke() and InvokeRepeating() .
Actually, consider using a tween library such as DOTween, iTween, etc.
think about events as a "broadcasting" system
关于变量名大小写的问题,个人偏好public和property用小写Camelcase,private用下划线小写Camelcase,因为这样与 Unity本身的命名是一致的。
- use Awake() to set up references and Begin() to initialize
- sometimes it's useful to implement some non-monobehaviour functions to be called by other scripts
if (hit.Rigidbody != null) {
doSomthing();
}
else {
Debug.Log("No Rigidbody attached to " + hit.name);
}
eg: Health.cs, Attack.cs
Data should only be assigned to public variables. Implementations should not contain any specific data.
A simple and nice implementation here: Unity3d-Finite-State-Machine
SendMessage(), BroadcastMessage() and SendMessageUpwards() use reflection and are therefore expensive. More importantly, they can result in ugly code and unexpectable errors.
UnityEvent is similar to C# delegate and event, but is also compatible with UI system.
The latter use string matching and is therefore more expensive.
example:
public class EnemyObject : MonoBehaviour
{
//-------------------------------------------------------
//C# accessors for private variables
public int Health
{
get{return _health;}
set
{
//Clamp health between 0-100
_health = Mathf.Clamp(value, 0, 100);
//Check if dead
if(_health <= 0)
{
OnDead();
return;
}
//Check health and raise event if required
if(_health <= 20)
{
OnHealthLow();
return;
}
}
}
//-------------------------------------------------------
public int Ammo
{
get{return _ammo;}
set
{
//Clamp ammo between 0-50
_ammo = Mathf.Clamp(value,0,50);
//Check if ammo empty
if(_ammo <= 0)
{
//Call expired event
OnAmmoExpired();
return;
}
}
}
Empty monobehaviour methods will still be called if not removed.
21. Make every public fields properties and serialize private fields to make them editable in the inspector.
This is for the sake of encapsulation.
public void Quit()
{
#if UNITY_EDITOR
UnityEditor.EditorApplication.isPlaying = false;
#else
Application.Quit();
#endif
}
Tooltip, Space, TextArea, Header, ExecuteinEditMode, ContextMenu, ContextMenuItem, Range, Multiline Attribute
because us string directly in Update() can be computationally expensive
using UnityEngine;
using System.Collections;
public class EthanScript : MonoBehaviour
{
Animator anim;
int jumpHash = Animator.StringToHash("Jump");
int runStateHash = Animator.StringToHash("Base Layer.Run");
void Start ()
{
anim = GetComponent<Animator>();
}
void Update ()
{
float move = Input.GetAxis ("Vertical");
anim.SetFloat("Speed", move);
AnimatorStateInfo stateInfo = anim.GetCurrentAnimatorStateInfo(0);
if(Input.GetKeyDown(KeyCode.Space) && stateInfo.nameHash == runStateHash)
{
anim.SetTrigger (jumpHash);
}
}
}
e.g: foot step sound in walk/jump animation
Premature optimization is evil!
- Add more code examples
- Add more tips on various topics
- Add more links to useful resources