unity3d programming
TRANSCRIPT
About me…(very shortly)
Ivanov Michael Lead Programmer R&D,Neurotech Solutions LTD Writer for Packt Publishing.,”Away3D Cookbook” Expert in Flex/AIR, Open Source Flash 3d engines. Spare time:Unity,UnrealEngine,OpenGL,Java3D Visit my tech blog:http://blog.alladvanced.net
About you(very shortly too)
How many of you have never heard of Unity? How many of you are designers ? How many of you come from Flash/ActionScript background? How many of you programmed in Unity? What language? How many of you accomplished commercial projects with
Unity ?
Disclaimer: During this short session we will attempt to cover:
Unity engine API model Unity programming paradigm Scripting Languages Scripting practices Unity GameObject structure Examples walkthrough
Disclaimer: this lecture doesn’t cover
How to program(You should learn by yourselves) Level design(designers –sorry) Advanced programming Shaders Much more cool and important stuff because of time limitation.
P.SFor the rest of disclaimer please refer to:GNU General Public LicenseStay tuned for Unity3D workshop announcement
Unity API
Audio EngineParticle System Engine
Terrain EnginePhysics Engine
GUI SystemAnimation Engine
Network API
Shaders programming API
Unity Engine Core
C#JavaScript
Boo(Python)
ShaderLab,Cg,GLSL
Sealed
Unity GameObject Paradigm
WindZone
LightCameraRigid Body Collider
Mesh Filter
Particle Emitter
Audio Source
Custom GameObject
Camera FPSController
AudioListener
GameObject
Shader Prefab Material
Script File AnimationAssets
Customized Game Object
Components
(Resource Library)
C# vs JavaScriptUnityScript(JavaScript) MONO(C#)
Pros •20X faster than web JS•Flexible coding(no need in data types declaration, no class body explicit typing required)•Beginners friendly•Well documented in Unity docs
•C family(fast adaptation for experienced devs)•Strong typing•Robust .NET Framework(Event Model,threads,structs and more C# specific)•External IDE software availability•Piles of docs in the Web•Portability to other platforms•DLL libs support
Cons •No explicit variable types declaration required•iPhone builds are bigger than C#(additional libs added)•language specific restrictions: No multi-dimensional arrays definition, no pass values by reference into functions(needs workaround),no Char data type , no multiple interface implementation only one class or interface are allowed to be extended•Poor Even Model(custom approach is slow)
•Partial implementation of .NET(no virtual classes allowed, no namespaces, limited multi-threading, Timer..•Less documented in Unity docs
C# vs JavaScript
class MyClass extends MonoBehaviour {
var myVar = 1;
function Start() { Debug.Log("hello world!"); }}
class MyClass : MonoBehaviour {
public int myVar = 1;
void Start() { Debug.Log("hello world!"); }}
Java Script C#
C# vs JavaScript
Surprisingly you can write with both of them in one project!(one way communication
only)
ScriptScriptScript
Script
Standard Assets((Compiled first
My Scripts Folder(Outside)(Compiled last)
C#JavaScript
ScriptScriptScript
Script
Typical application design model
PlayerGameObject
EnemyGameObject
WeaponPickUps
GameObjectGUI ModuleGameObject
Script ScriptScript
ScriptScript
ScriptScript
Script
(Main))(GameObject
(Entry point)Script
ScoreManager
SoundManager
LevelManager
BackEndManager
Script ScriptScriptScript
GameObject Class structure
using UnityEngine;using System.Collections;
public class MyNewBehaviour : MonoBehaviour {
public static AudioClip playingClip;//////---accessible from outside to allvoid Start () {
}
void Update () {///////// see also FixedUpdate
} void OnMouseDown(){
} void OnCollisionEnter(){
} public void SpawnEnemy(){////////-------------------your custom method
}}
Demo App
“TF2 Dancing Spy” demo
“Dancing Spy” App Structure
FPSController
SceneManager
CharacterManagerAudioManager
GUIManager
Generic Scripts
VideoManager
LightProjector
AnimatedCamera
ScriptsInit
DirectionalLight
TileManager
SpectrumReader
ProjectorTransformer
WallGenerator
Tile(dynamic add)
WallSyntezator
iTweenUtils
Spy
Monitor1
Monitor2
Monitor3
“Dancing Spy” UML
FPSControllerSceneManager
CharacterManager
AudioManager GUIManager
Generic Scripts
VideoManager
LightProjector
AnimatedCamera
DirectionalLight
TileManager
SpectrumReader
ProjectorTransformer
WallGenerator
Tile(dynamic add)
WallSyntezator
iTween
Spy
Animation
Button
Resources
MP3
MP3
Generic Scripts
iTweenMonitor1Monitor2
video
Vehicles and PhysX
Hovermobile Demo
Mesh manipulation(or how to blow thing up)
Fire Ball Demo
Common scripting concepts and operations
Time
Time.time Time.deltaTime C# System.Timers.Timer
Update() and FixedUpdate()
FixedUpdate synchronized with Physics Engine steps while Update() runs on each frame
Always use FixedUpdate() for physics!
F F F F F0.1 seconds0.0 seconds
U U U U U U U U U U
Time
Time.time Time.deltaTime C# System.Timers.Timer
Update() and FixedUpdate()
FixedUpdate synchronized with Physics Engine steps while Update() runs on each frame
Always use FixedUpdate() for physics!
F F F F F0.1 seconds0.0 seconds
U U U U U U U U U U
Accessing Objects
TileManager tlm = tile.GetComponent<TileManager> ();
void locateAndAssignCams(){camFPS=GameObject.Find("Main Camera");camAnim=GameObject.Find("AnimatedCam");
}
Public variables reference.(Set via component interface)•GetComponent:
•Find() ,FindObjectOfType(),FindObjectsOfType()Light light = FindObjectOfType(typeof(Light));
if(AudioManager.spectrumData!=null&&AudioManager.spectrumData.Length>0){currentSpectrum=AudioManager.spectrumData;
}
Direct access via static members
Dynamic creation/instantiation
AudioClip aclip=(AudioClip)Resources.Load("Sounds/gagaSong");
_audioSource.clip=aclip;playingClip=aclip;_audioSource.Play();
Create object in runtime:
Instantiate PrefabGameObject tile = (GameObject)Instantiate (tilePF, Vector3.zero, Quaternion.identity);
void Start () {_light=new GameObject("Light1");_light.AddComponent<Light>();_light.light.type=LightType.Point;_light.light.range=400;_light.light.color=Color.red;_light.transform.Translate(new
Vector3(1000,200,1000)); }
Dynamic resource assets loading
Math (Shortest Math primer ever)
What are these matrices and vectors anyways?Core Classes: Mathf .(Also C# System.Math ) Matrix4x4 Vector2/3/4 Quaternion –all Rotations are Quaternion based
Unity Physics
“In Physics Land talk Physics”
Unity Physics
Core Classes:•Physics- Global physics properties and helper methods.•RigidBody-contains all essential physics methods and properties for a body
Unity Physics
AddTorque()
RigidBody
SpaceCraftGameObject
gravity
AddForce)(
Collid
ers
AddForceAtPosition()
Components attachment
Self attachment
_audioSource=gameObject.AddComponent<AudioSource>();
Indirect attachment
GameObject tile = (GameObject)Instantiate (tilePF, Vector3.zero, Quaternion.identity);
AudioSource audioSource=tile.AddComponent<AudioSource>();//adding audio source component to the tile and accessing it at the same time//
Yield & Coroutines
YieldEnsures that the function will continue from the line after the yield
statement next time it is calledCan’t be used inside “Time” methods like Update(),FixedUpdate()
CoroutineSuspends its execution until given Yield instruction finishes.Requires a method to be IEnumerator
Yield & Coroutines
IEnumerator Start (){print ("first");yield return new WaitForSeconds(2f);print ("2 seconds later");
}
Yield
Yield & Coroutines
using UnityEngine;using System.Collections;public class StupidLoop : MonoBehaviour {private bool buttonPressed= false;
void Update (){ if(!buttonPressed) {
if(Input.GetButtonDown("Jump")){ StartGame();}
}print("looping...");}
void StartGame(){
buttonPressed= true;print("Game Started");
}
}
No Yield & Coroutines scenario(Ugly one)
Yield & Coroutines
void Start(){StartCoroutine(WaitForKeyPress("Jump"));
}public IEnumerator WaitForKeyPress(string _button){
while(!buttonPresed){ if(Input.GetButtonDown (_button)) {
StartGame(); yield break; }
print("Awaiting key input.");yield return 0;}
}
private void StartGame(){buttonPressed= true;print("Starting the game officially!");}
}
Simple example
Yield & Coroutines
void Start () { glEffect=GameObject.Find("Main
Camera").GetComponent<GlowEffect>();StartCoroutine("explodeCounter");
}IEnumerator explodeCounter(){
onTimerElaps();if(amount<15){
yield return new WaitForSeconds(0.01F);}else{
Mesh myMesh = GetComponent<MeshFilter>().mesh;GameObject.Destroy(myMesh);yield break;
}
StartCoroutine("explodeCounter");
}void onTimerElaps(){
amount+=Mathf.Sin(Time.time)/5;glEffect.glowIntensity=amount/2;ExplodeMesh(amount);
}
Practical example
Yield & Coroutines
IEnumerator Start () { yield return StartCoroutine(MyWaitFunction (4.0f)); print ("4 seconds passed"); yield return StartCoroutine(MyWaitFunction (5.0f)); print ("9 seconds passed"); }
IEnumerator MyWaitFunction (float delay) { float timer = Time.time + delay; while (Time.time < timer) {
Debug.Log(Time.time); yield return true; } }
Sequential Coroutines calls
Unity Event Model & alternatives
Unity built-in event system SendMessage()- Calls the method on every MonoBehaviour in this
game object. BroadcastMessage()- Calls the method on every MonoBehaviour
in this game object or any of its children.Downside:Need to target methods by their name (Errors prone)Work only within the object's transform hierarchy
Controller Class registers all the classes to be notified of changes via reference
Downside :Flexibility & ScalabilityNightmare for big projects
C# Events Model
Dispatcher classpublic class EventSender : MonoBehaviour { public delegate void GameObjectPressHandler(GameObject e); public event GameObjectPressHandler OnGameObjectPress; private void DispatchPressEvent () { if (OnGameObjectPress != null){ OnGameObjectPress (this.gameObject);//event has been fired! } }}
public GameObject gm;
EventSender myEventSender=gm.getComponent<EventSender>();myEventSender.OnGameObjectPress+=new GameObjectPressHandler(onGMPress);Private void onGMPress(GameObjject gm){ print(gm+”was has been!”);}
Listener Class
Unity3D
Thank you and good luck!