Differences

This shows you the differences between two versions of the page.

Link to this comparison view

pjv:laboratoare:2022:01 [2022/10/19 08:04]
alexandru.gradinaru
pjv:laboratoare:2022:01 [2022/10/19 08:07] (current)
alexandru.gradinaru [Unity Scripting]
Line 110: Line 110:
   * This is useful to ensure all other Update related calculation is complete and other dependent calculation can be called.   * This is useful to ensure all other Update related calculation is complete and other dependent calculation can be called.
   * For example, if you need to integrate a third-person camera to follow any object; then it should be implemented inside the LateUpdate. It is make sure that camera will track the object after its movement and rotation update.   * For example, if you need to integrate a third-person camera to follow any object; then it should be implemented inside the LateUpdate. It is make sure that camera will track the object after its movement and rotation update.
- 
- 
-> **time.deltatime** 
- 
-In unity, Time.deltaTime will provide you **time in seconds it took to complete the last frame (Read Only)**. This can be used to make your game frame independent. 
- 
-When you multiply any value with Time.deltaTime you essentially express: I want to move this object 10 meters per second instead of 10 meters per frame. 
- 
-For more details please visit  "Edit -> Project Settings -> Time"​ **OR** From scripting, check out the [Time](http://​docs.unity3d.com/​ScriptReference/​Time.html) class. 
- 
-<code c#> 
- 
-public class ExampleClass : MonoBehaviour { 
-    void Update() { 
-        float translation = Time.deltaTime * 10; 
-        transform.Translate(0,​ 0, translation);​ 
-    } 
-} 
- 
-</​code>​ 
- 
-> **Coroutines** 
- 
-While Coroutines seem to work like threads at first glance, they actually aren't using any multithreading. They are executed sequentially until they `yield`. Coroutine might seem like it is a thread, but coroutines execute within the main thread. 
- 
-The difference between a coroutine and a thread is very much like the difference between [cooperative multitasking](https://​en.wikipedia.org/​wiki/​Cooperative_multitasking) and [preemptive multitasking](https://​en.wikipedia.org/​wiki/​Preemption_(computing)). Note that a coroutine runs on the main thread and must voluntarily yield control back to it, if control is not yielded (this is where the coroutine must be _cooperative_) then your coroutine will hang your main thread, thus hanging your game. 
- 
-The disadvantage of not doing "​real"​ multithreading is that you can not use coroutines to parallelize CPU-intense calculations over multiple CPU cores.  With the release of Unity 2017, it is now possible to use a new C# feature called [**async-await**](https://​blogs.msdn.microsoft.com/​appconsult/​2017/​09/​01/​unity-coroutine-tap-en-us/​) for our asynchronous methods instead. This comes with a lot of nice features compared to coroutines. 
- 
-**Let'​s look at a simple example. Given the following coroutine:​** 
- 
-<code c#> 
-public class AsyncExample : MonoBehaviour 
-{ 
-    IEnumerator Start() 
-    { 
-        Debug.Log("​Waiting 1 second..."​);​ 
-        yield return new WaitForSeconds(1.0f);​ 
-        Debug.Log("​Done!"​);​ 
-    } 
-} 
-</​code>​ 
- 
-**The equivalent way to do this using async-await would be the following:​** 
- 
-<code c#> 
-public class AsyncExample : MonoBehaviour 
-{ 
-    async void Start() 
-    { 
-        Debug.Log("​Waiting 1 second..."​);​ 
-        await Task.Delay(TimeSpan.FromSeconds(1));​ 
-        Debug.Log("​Done!"​);​ 
-    } 
-} 
-</​code>​ 
- 
-<note tip> 
-Conclusion: 
- 
-  * If you want to use asynchronous execution to express game logic, use coroutines. 
-  * If you want to use asynchronous execution to utilize multiple CPU cores, use threads. 
-</​note>​ 
  
 > **Script compilation order inside Unity** > **Script compilation order inside Unity**
Line 186: Line 123:
  
 A common example of the significance of this order occurs when a UnityScript file needs to reference a class defined in a C# file. To achieve this, you need to place the C# file inside a Plugins folder, and the UnityScript file in a non-special folder. Because C# code is compiled before JS code, so in general, while JS code can access C# classes, the opposite is not possible If you don't do this, an error is thrown saying that the C# class cannot be found. A common example of the significance of this order occurs when a UnityScript file needs to reference a class defined in a C# file. To achieve this, you need to place the C# file inside a Plugins folder, and the UnityScript file in a non-special folder. Because C# code is compiled before JS code, so in general, while JS code can access C# classes, the opposite is not possible If you don't do this, an error is thrown saying that the C# class cannot be found.
- 
-=== C# Basics === 
- 
-> **Static Classes and Singleton** 
- 
-Both can be invoked without instantiation,​ both provide only one "​Instance"​ and neither of them is thread-safe. 
- 
-A [static](https://​docs.microsoft.com/​en-us/​dotnet/​csharp/​language-reference/​keywords/​static) class is basically the same as a non-static class, but there is one difference: a static class contains only static members and a private constructor and cannot be instantiated. In other words, you cannot use the [new](https://​docs.microsoft.com/​en-us/​dotnet/​csharp/​language-reference/​keywords/​new) keyword to create a variable of the class type. The design style embodied in a static class is purely procedural. 
- 
-Singleton, on the other hand, is a pattern specific to OO design. It is an instance of an object (with all the possibilities inherent in that, such as polymorphism),​ with a creation procedure that ensures that there is only ever one instance of that particular role over its entire lifetime. 
- 
-> **The Virtual keyword** 
- 
-The **'​virtual'​** keyword is used to modify a method, property, indexer, or event declaration and allow for it to be overridden in a derived class. By default, methods are non-virtual and you cannot override a non-virtual method. You cannot use the `virtual` modifier with the `static`,​ `abstract`,​ `private`,​ or `override`modifiers. 
- 
-For example, this method can be overridden by any class that inherits it: 
- 
-<code c#> 
-public virtual double Area() 
-{ 
-    return x * y; 
-} 
-</​code>​ 
- 
-> **Abstract Classes and interfaces** 
- 
-An **abstract class** is a special kind of class that cannot be instantiated. An abstract class is only to be sub-classed (inherited from). In other words, it only allows other classes to inherit from it but cannot be instantiated. 
- 
-When we create an interface, we are basically creating a set of methods without any implementation that must be overridden by the implemented classes. The advantage is that it provides a way for a class to be a part of two classes: one from inheritance hierarchy and one from the interface. 
- 
-When we create an abstract class, we are creating a base class that might have one or more completed methods but at least one or more methods are left uncompleted and declared `abstract`. If all the methods of an abstract class are uncompleted then it is same as an interface. The purpose of an abstract class is to provide a base class definition for how a set of derived classes will work and then allow the programmers to fill the implementation in the derived classes. 
- 
-There are some similarities and differences between an interface and an abstract class that I have arranged in a table for easier comparison: 
- 
-| **Feature** | **Interface** | **Abstract class** | 
-| --- | --- | --- | 
-| **Multiple inheritances** | A class may inherit several interfaces. | A class may inherit only one abstract class. | 
-| **Default implementation** | An interface cannot provide any code, just the signature. | An abstract class can provide complete, default code and/or just the details that have to be overridden. | 
-| **Access Modfiers** | An interface cannot have access modifiers for the subs, functions, properties etc everything is assumed as public | An abstract class can contain access modifiers for the subs, functions, properties | 
-| **Core VS Peripheral** | Interfaces are used to define the peripheral abilities of a class. In other words both Human and Vehicle can inherit from a IMovable interface. | An abstract class defines the core identity of a class and there it is used for objects of the same type. | 
- 
-> **Serialization and De-Serialization** 
- 
-**Serialization:​** 
- 
-Serialization is the process of converting an object into a stream of bytes to store the object or transmit it to memory, a database, or a file. Its main purpose is to save the state of an object in order to be able to recreate it when needed. The reverse process is called deserialization. 
- 
-{{ https://​docs.microsoft.com/​en-us/​dotnet/​csharp/​programming-guide/​concepts/​serialization/​media/​serialization.gif?​400 |}} 
- 
-The object is serialized to a stream, which carries not just the data, but information about the object'​s type, such as its version, culture, and assembly name. From that stream, it can be stored in a database, a file, or memory. 
- 
-Serialization allows the developer to save the state of an object and recreate it as needed, providing storage of objects as well as data exchange. 
- 
-**Deserialization:​** 
- 
-As the name suggests, deserialization is the reverse process of serialization. It is the process of getting back the serialized object so that it can be loaded into memory. It resurrects the state of the object by setting properties, fields etc. 
- 
-**Types of serialization:​** 
- 
-  - Binary Serialization 
-  - XML Serialization 
-  - JSON Serialization 
- 
-> **Methods and functions** 
- 
-A **function** is a piece of code that is called by name. It can be passed data to operate on (i.e. the parameters) and can optionally return data (the return value). All data that is passed to a function is explicitly passed. 
- 
-A **method** is a piece of code that is called by a name that is associated with an object. In most respects it is identical to a function except for two key differences:​ 
- 
-  - A method is implicitly passed the object on which it was called. 
-  - A method is able to operate on data that is contained within the class (remembering that an object is an instance of a class – the class is the definition, the object is an instance of that data). 
- 
-> **Generic Functions and Generic Classes** 
- 
-Generic classes encapsulate operations that are not specific to a particular data type. The most common use for generic classes is with collections like linked lists, hash tables, stacks, queues, trees, and so on. Operations such as adding and removing items from the collection are performed in basically the same way regardless of the type of data being stored. 
- 
-Generic functions are similarly those which describe the algorithm without specifying a particular data type. 
  
 === Unity C# References === === Unity C# References ===
Line 309: Line 169:
 <code c#> <code c#>
 private void FixedUpdate() { /* Called every Fixed Timestep */ } private void FixedUpdate() { /* Called every Fixed Timestep */ }
-</​code>​ 
- 
-> **GameObject Manipulation** 
- 
-<code c#> 
-/* Create a GameObject */ 
-Instantiate(GameObject prefab); 
-Instantiate(GameObject prefab, Transform parent); 
-Instantiate(GameObject prefab, Vector3 position, Quaternion rotation); 
-/* In Practice */ 
-Instantiate(bullet);​ 
-Instantiate(bullet,​ bulletSpawn.transform);​ 
-Instantiate(bullet,​ Vector3.zero,​ Quaternion.identity);​ 
-Instantiate(bullet,​ new Vector3(0, 0, 10), bullet.transform.rotation);​ 
- 
-newobj = Instantiate(objTemplate) as ObjType; 
- 
-//from pregab - prefab must be in Resources folder 
-newobj1 = Instantiate(Resources.Load("​enemy"​));​ 
- 
-// Instantiate the projectile at the position and rotation of this transform 
-Rigidbody projectile; 
-Rigidbody clone; 
-clone = Instantiate(projectile,​ transform.position,​ transform.rotation);​ 
- 
-enemyOrc = Instantiate(Orc) as Enemy; 
- 
-/* Destroy a GameObject */ 
-Destroy(gameObject);​ 
- 
-/* Finding GameObjects */ 
-GameObject myObj = GameObject.Find("​NAME IN HIERARCHY"​);​ 
-GameObject myObj = GameObject.FindWithTag("​TAG"​);​ 
-childObject=parentObject.GetChild("​child_name"​);​ 
-parentObject.GetChild("​child_name"​).GetComponent<​SpriteRenderer>​().sprite = image; ​ 
- 
-/* Accessing Components */ 
-Example myComponent = GetComponent<​Example>​();​ 
-AudioSource audioSource = GetComponent<​AudioSource>​();​ 
-Rigidbody rgbd = GetComponent<​Rigidbody>​();​ 
-GetComponent<​SpriteRenderer>​().sprite = image; //set image in child component 
-GetComponent<​Text>​().text = '​123'​ //set text 
- 
-/* Transforms - can be accessed using the `transform` attribute */ 
-Vector3 objectPosition = gameObject.transform.position;​ 
-gameObject.transform.position = new Vector3(posX,​ posY, posZ); 
-transform.Translate(Vector3.up * Time.deltaTime,​ Space.World);​ 
-transform.Rotate(Vector3.up * Time.deltaTime,​ Space.World);​ 
- 
-/* Activate - can hide or how an element from the scene*/ 
-myObject.SetActive(false);​ // hide 
-myObject.SetActive(true);​ // show 
- 
-GetComponent<​BoxCollider>​().SetActive(false);​ // hide component 
- 
-</​code>​ 
- 
-> **Vector Quick Reference** 
- 
-X = Left/​Right ​  Y = Up/​Down ​  Z = Forward/​Back 
- 
-<code c#> 
-Vector3.right /* (1, 0, 0) */   ​Vector2.right /* (1, 0) */ 
-Vector3.left /* (-1, 0, 0) */   ​Vector2.left /* (-1, 0) */ 
-Vector3.up /* (0, 1, 0) */      Vector2.up /* (0, 1) */ 
-Vector3.down /* (0, -1, 0) */   ​Vector2.down /* (0, -1) */ 
-Vector3.forward /* (0, 0, 1) */ 
-Vector3.back /* (0, 0, -1) */ 
-Vector3.zero /* (0, 0, 0) */    Vector2.zero /* (0, 0) */ 
-Vector3.one /* (1, 1, 1) */     ​Vector2.one /* (1, 1) */ 
-float length = myVector.magnitude /* Length of this Vector */ 
-myVector.normalized /* Keeps direction, but reduces length to 1 */ 
- 
-</​code>​ 
- 
-> **Time Variables** 
- 
-<code c#> 
-/* The time in seconds since the start of the game */ 
-float timeSinceStartOfGame = Time.time; 
- 
-/* The scale at which the time is passing */ 
-float currentTimeScale = Time.timeScale;​ 
-/* Pause time */ 
-Time.timeScale = 0; 
- 
-/* The time in seconds it took to complete the last frame */ 
-/* Use with Update() and LateUpdate() */ 
-float timePassedSinceLastFrame = Time.deltaTime;​ 
- 
-/* The interval in seconds at which physics and fixed frame rate updates are performed */ 
-/* Use with FixedUpdate() */ 
-float physicsInterval =  Time.fixedDeltaTime;​ 
- 
-</​code>​ 
- 
-> **Random values** 
- 
-<code c#> 
-Random.Range(-10.0f,​ 10.0f) 
-Random.Range(0,​ 8); 
-</​code>​ 
- 
-> **Physics Events** 
- 
-<code c#> 
-/* Both objects have to have a Collider and one object has to have a Rigidbody for these Events to work */ 
-private void OnCollisionEnter(Collision hit) { Debug.Log(gameObject.name + " just hit " + hit.gameObject.name);​ } 
-private void OnCollisionStay(Collision hit) { Debug.Log(gameObject.name + " is hitting " + hit.gameObject.name);​ } 
-private void OnCollisionExit(Collision hit) { Debug.Log(gameObject.name + " stopped hitting " + hit.gameObject.name);​ } 
- 
-/* Trigger must be checked on one of the Colliders */ 
-private void OnTriggerEnter(Collider hit) { Debug.Log(gameObject.name + " just hit " + hit.name); } 
-private void OnTriggerStay(Collider hit) { Debug.Log(gameObject.name + " is hitting " + hit.name); } 
-private void OnTriggerExit(Collider hit) { Debug.Log(gameObject.name + " stopped hitting " + hit.name); } 
-  
-/* For 2D Colliders just add 2D to the Method name and the Parameter Type */ 
-private void OnCollisionEnter2D(Collision2D hit) { } 
-private void OnCollisionStay2D(Collision2D hit) { } 
-private void OnCollisionExit2D(Collision2D hit) { } 
-private void OnTriggerEnter2D(Collider2D hit) { } 
-private void OnTriggerStay2D(Collider2D hit) { } 
-private void OnTriggerExit2D(Collider2D hit) { } 
- 
-</​code>​ 
- 
-> **Coroutines** 
- 
-<code c#> 
-/* Create a Coroutine */ 
-private IEnumerator CountSeconds(int count = 10) 
-{ 
-  for (int i = 0; i <= count; i++) { 
-    Debug.Log(i + " second(s) have passed"​);​ 
-    yield return new WaitForSeconds(1.0f);​ 
-  } 
-} 
- 
-/* Call a Coroutine */ 
-StartCoroutine(CountSeconds());​ 
-StartCoroutine(CountSeconds(10));​ 
- 
-/* Call a Coroutine that may need to be stopped */ 
-StartCoroutine("​CountSeconds"​);​ 
-StartCoroutine("​CountSeconds",​ 10); 
- 
-/* Stop a Coroutine */ 
-StopCoroutine("​CountSeconds"​);​ 
-StopAllCoroutines();​ 
- 
-/* Store and call a Coroutine from a variable */ 
-private IEnumerator countSecondsCoroutine;​ 
- 
-countSecondsCoroutine = CountSeconds();​ 
-StartCoroutine(countSecondsCoroutine);​ 
- 
-/* Stop a stored Coroutine */ 
-StopCoroutine(countSecondsCoroutine);​ 
- 
-/* Coroutine Return Types */ 
-yield return null; // Waits until the next Update() call 
-yield return new WaitForFixedUpdate();​ // Waits until the next FixedUpdate() call 
-yield return new WaitForEndOfFrame();​ // Waits until everything this frame has executed 
-yield return new WaitForSeconds(float seconds); // Waits for game time in seconds 
-yield return new WaitUntil(() => MY_CONDITION);​ // Waits until a custom condition is met 
-yield return new WWW("​MY/​WEB/​REQUEST"​);​ // Waits for a web request 
-yield return StartCoroutine("​MY_COROUTINE"​);​ // Waits until another Coroutine is completed 
- 
-</​code>​ 
- 
-> **Input Quick Reference** 
- 
-<code c#> 
-if (Input.GetKeyDown(KeyCode.Space)) { Debug.Log("​Space key was Pressed"​);​ } 
-if (Input.GetKeyUp(KeyCode.W)) { Debug.Log("​W key was Released"​);​ } 
-if (Input.GetKey(KeyCode.UpArrow)) { Debug.Log("​Up Arrow key is being held down"​);​ } 
- 
-/* Button Input located under Edit >> Project Settings >> Input */ 
-if (Input.GetButtonDown("​ButtonName"​)) { Debug.Log("​Button was pressed"​);​ } 
-if (Input.GetButtonUp("​ButtonName"​)) { Debug.Log("​Button was released"​);​ } 
-if (Input.GetButton("​ButtonName"​)) { Debug.Log("​Button is being held down"​);​ } 
- 
-float translation = Input.GetAxis("​Vertical"​) * speed; 
-float rotation = Input.GetAxis("​Horizontal"​) * rotationSpeed;​ 
- 
-// Make it move 10 meters per second instead of 10 meters per frame... 
-translation *= Time.deltaTime;​ 
-rotation *= Time.deltaTime;​ 
- 
-// Move translation along the object'​s z-axis 
-transform.Translate(0,​ 0, translation);​ 
- 
-// Rotate around our y-axis 
-transform.Rotate(0,​ rotation, 0); 
- 
-/* special input events */ 
-// OnMouseDown is called when the user has pressed the mouse button while over the Collider. 
-// This event is sent to all scripts of the GameObject with Collider or GUI Element. Scripts of the parent or child objects do not receive this event. 
-// This function is not called on objects that belong to Ignore Raycast layer. 
-// This function is called on Colliders marked as Trigger if and only if Physics.queriesHitTriggers is true. 
-void OnMouseDown() 
-{ 
-    // Destroy the gameObject after clicking on it 
-    Destroy(gameObject);​ 
- 
- 
 </​code>​ </​code>​
  
pjv/laboratoare/2022/01.1666155882.txt.gz · Last modified: 2022/10/19 08:04 by alexandru.gradinaru
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0