Showing posts with label C#. Show all posts
Showing posts with label C#. Show all posts
Monday, May 20, 2019
Building large worlds in Unity.
I made something which lets you render very large worlds with a small farClipPlane.
https://github.com/simonwittber/scaled-origin
The demo shows an earth sized planet viewed from about 1000km altitude. It's great for Space Games, like this one I've been working on recently.
Tuesday, February 12, 2019
Thursday, September 06, 2018
.Net reflection is expensive in more ways than I thought...
Enter statements below. csharp> var t = typeof(int); csharp> Object.ReferenceEquals(t.AssemblyQualifiedName, t.AssemblyQualifiedName); falseEvery access to the AssemblyQualifiedName property does some lookup work… and returns a NEW copy of the string.
It’s _almost_ as if one might recommend caching every property, because you never know what it might be doing, and avoid creating auto properties (in place of public fields), so that you know when there is no need to cache the value.
Wednesday, July 18, 2018
Faster Update calls for Unity!
These MonoBehaviour classes allow for batch updating of all components in a single call. KinematicMotor example provided. It's a gentle solution to the 1k update calls problem.
AssetForge Model Optimizer for Unity
A Unity post processor to optimize meshes created with AssetForge. Reduces draw calls, combines meshes and allows batching.
Thursday, March 01, 2018
Thursday, February 22, 2018
A unique ID for your Serialized classes in Unity.
Note, the GetHashCode() method will probably return a unique ID. There is a very remote chance you will get a clashing ID.
Update:After further experiments, I believe this does not work well enough to be generally useful. Unity, we need a new serialization system!
Wednesday, February 21, 2018
Synthesizing Sound Effects in Unity3D.
I have built a Synthesizer for creating sound effects in Unity. It fills a similar niche to SFXR/BFXR, but aims to have more quality and versatility. It's fully modular, with all parameters able to be modulated via the Unity AnimationCurve.
I have called it 'Fizzle'.
Source coming soon.
I have called it 'Fizzle'.
Source coming soon.
Wednesday, February 14, 2018
Supercharged Gizmos for your SceneView
This code shows how I use the [DrawGizmo] attribute to create special gizmos for my components, which only appear when you're actually near the component.
Tuesday, February 13, 2018
Thursday, February 08, 2018
Friday, November 10, 2017
Friday, September 15, 2017
Avoid FindObjectsOfType with this Pattern
public class SomeComponent : MonoBehaviour { public static List<SomeComponent> Instances = new List<SomeComponent>(); private int instanceIndex = -1; void OnDisable() { var lastIndex = Instances.Count - 1; Instances[instanceIndex] = Instances[lastIndex]; Instances[instanceIndex].instanceIndex = instanceIndex; Instances.RemoveAt(lastIndex); } void OnEnable() { Instances.Add(this); instanceIndex = Instances.Count - 1; } }
Tuesday, August 22, 2017
Vector3.sqrMagnitude vs Vector3.magntiude
sqrMagnitude is 20% faster than magnitude.
magnitude: 0.862013
srqMagnitude: 0.689175
using System.Collections; using System.Collections.Generic; using UnityEngine; using System.Diagnostics; public class MagVsSqrMag : MonoBehaviour { void Start() { var C = 10000000f; var sw = new Stopwatch(); var vec = new Vector3(Random.value, Random.value, Random.value); var r = 0f; for (var i = 0; i < C; i++) { sw.Start(); r += vec.magnitude; sw.Stop(); } UnityEngine.Debug.Log("magnitude:" + (sw.ElapsedTicks / C)); sw.Reset(); vec = new Vector3(Random.value, Random.value, Random.value); for (var i = 0; i < C; i++) { sw.Start(); r += vec.sqrMagnitude; sw.Stop(); } UnityEngine.Debug.Log("srqMagnitude:" + (sw.ElapsedTicks / C)); UnityEngine.Debug.Log(r); } }
Monday, February 13, 2017
Take a Unity Screenshot with Alpha
This script takes a screenshot and saves it to the user desktop. It has options to use an alpha background, and also upscale the image. Useful for taking pictures of a scene or model for composition by artists.
using UnityEngine; using System.IO; using System; [RequireComponent (typeof(Camera))] public class CaptureWithAlpha : MonoBehaviour { public int UpScale = 4; public bool AlphaBackground = true; Texture2D Screenshot () { var camera = GetComponent<Camera> (); int w = camera.pixelWidth * UpScale; int h = camera.pixelHeight * UpScale; var rt = new RenderTexture (w, h, 32); camera.targetTexture = rt; var screenShot = new Texture2D (w, h, TextureFormat.ARGB32, false); var clearFlags = camera.clearFlags; if (AlphaBackground) { camera.clearFlags = CameraClearFlags.SolidColor; camera.backgroundColor = new Color (0, 0, 0, 0); } camera.Render (); RenderTexture.active = rt; screenShot.ReadPixels (new Rect (0, 0, w, h), 0, 0); screenShot.Apply (); camera.targetTexture = null; RenderTexture.active = null; DestroyImmediate (rt); camera.clearFlags = clearFlags; return screenShot; } [ContextMenu ("Capture Screenshot")] public void SaveScreenshot () { var path = Environment.GetFolderPath (Environment.SpecialFolder.Desktop); var filename = "SS-" + DateTime.Now.ToString ("yyyy.MM.dd.HH.mm.ss") + ".png"; File.WriteAllBytes (Path.Combine (path, filename), Screenshot ().EncodeToPNG ()); } }
Wednesday, January 25, 2017
A HTTP server embedded inside Unity3D.
Just 514 lines of code. Uses sockets only, no other dependencies.
https://github.com/simonwittber/uniwebserver
Example Component:
https://github.com/simonwittber/uniwebserver
Example Component:
[RequireComponent(typeof(EmbeddedWebServerComponent))] public class FileUpload : MonoBehaviour, IWebResource { public string path = "/upload"; public TextAsset html; EmbeddedWebServerComponent server; void Start () { server = GetComponent<EmbeddedWebServerComponent>(); server.AddResource(path, this); } public void HandleRequest (Request request, Response response) { response.statusCode = 200; response.message = "OK."; response.Write(html.text); } }
Tuesday, January 03, 2017
Is the Unity3D GameObject.GetComponent method slow?
TLDR; No, not really.
Update: Actually, it is slow if you are using IL2CPP. Test results are GetComponent:350, Field:50, Dict:290.
Using the below test script, using GetComponent is about 3x slower than using a direct reference. Caching the return calue in a Dictionary, is slightly faster.
A typical result for me is 232 GetComponent(), 74 for private field and 201 for a dictionary lookup. If you use a builtin Unity type, like Transform, GetComponent is twice as fast.
I made sure the compiler was not optimising out my tests by putting in some fake 'xyzzy' work which is not included in the timing.
Why this simple test? I'm proving to myself it is not terribly bad to use a GetComponent call in an update loop, or keep a Dictionary cache. The call itself is so fast (0.000000232 seconds) that there is really no issue using it a few times inside an update loop.
Update: Actually, it is slow if you are using IL2CPP. Test results are GetComponent:350, Field:50, Dict:290.
Using the below test script, using GetComponent is about 3x slower than using a direct reference. Caching the return calue in a Dictionary, is slightly faster.
A typical result for me is 232 GetComponent(), 74 for private field and 201 for a dictionary lookup. If you use a builtin Unity type, like Transform, GetComponent is twice as fast.
I made sure the compiler was not optimising out my tests by putting in some fake 'xyzzy' work which is not included in the timing.
Why this simple test? I'm proving to myself it is not terribly bad to use a GetComponent call in an update loop, or keep a Dictionary cache. The call itself is so fast (0.000000232 seconds) that there is really no issue using it a few times inside an update loop.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GetComponentTest : MonoBehaviour {
public int iterations = 1000000;
GetComponentTest testComponentB, testComponentA;
Dictionary<System.Type, Component> cache = new Dictionary<System.Type, Component>();
void Start () {
var sw = new System.Diagnostics.Stopwatch();
for(var i=0; i<iterations; i++) {
sw.Start();
var r = GetComponent<GetComponentTest>();
sw.Stop ();
if(r.name == "xyzzy") {
Debug.Log("xyzzy");
}
}
Debug.Log(sw.ElapsedMilliseconds);
testComponentB = GetComponent<GetComponentTest>();
sw.Reset();
for(var i=0; i<iterations; i++) {
sw.Start();
testComponentA = testComponentB;
sw.Stop ();
if(testComponentA.name == "xyzzy") {
Debug.Log("xyzzy");
}
}
Debug.Log(sw.ElapsedMilliseconds);
sw.Reset();
cache[typeof(GetComponentTest)] = GetComponent<GetComponentTest>();
sw.Reset();
for(var i=0; i<iterations; i++) {
sw.Start();
testComponentA = cache[typeof(GetComponentTest)] as GetComponentTest;
sw.Stop ();
if(testComponentA.name == "xyzzy") {
Debug.Log("xyzzy");
}
}
Debug.Log(sw.ElapsedMilliseconds);
sw.Reset();
}
}
Wednesday, December 09, 2015
Implicit typing in C# using "var"
I use the var keyword everywhere. Someone told me today that this is a bad practice, because "sometimes you can't tell what type it is".
Well, I disagree. I believe we generally don't care what type a variable is, we care about how we use it, the interface it provides to the programmer. For example:
Finally, var lets me write less characters, which often means less backspacing and retyping!
This well written post describing more advantages of implicit typing. To Summarise:
Well, I disagree. I believe we generally don't care what type a variable is, we care about how we use it, the interface it provides to the programmer. For example:
foreach(var i in myListOfThings) { Debug.Log(i.name); }I don't care what typeof(i) is, I just want to know it has a .name attribute. If I change the type later, I probably still want it to have a .name attribute, and the var keyword lets this code keep working. Also:
var v = new Vector3(0,0,0); //vs Vector3 v = new Vector3(0,0,0);In this case, the Vector3 type declaration is redundant, it is simply repeating information already on the same line. Remember, repeating yourself in code is a Bad Thing. Later on if I realise my Vector3 variables need to be Vector2 variables, I need to change the type information in 2 places for each variable. Yuck.
Finally, var lets me write less characters, which often means less backspacing and retyping!
var now = System.DateTime.Now; //or System.DateTime now = System.DateTime.Now;
This well written post describing more advantages of implicit typing. To Summarise:
- It induces better naming for local variables.
- It induces better API.
- It induces variable initialisation.
- It removes code noise.
- It doesn't require the using directive.
Saturday, July 18, 2015
AsyncCoroutines - Rather Easy Multithreading for Unity
This is a tiny little library to help you use your multicore CPU in Unity3D.
I've made a brief video overview and the package will be available on the asset store very soon.
It includes a task viewer, which is similar to the process viewer on your operating system. It shows which coroutines are running in the background and foreground, which coroutines are waiting for execution, and how many CPU ticks each coroutine consumes per frame.
To use, make sure you have:
I've made a brief video overview and the package will be available on the asset store very soon.
It includes a task viewer, which is similar to the process viewer on your operating system. It shows which coroutines are running in the background and foreground, which coroutines are waiting for execution, and how many CPU ticks each coroutine consumes per frame.
To use, make sure you have:
using AsyncCoroutines;at the top of your script file. Below is an example of a coroutine method which can be started using:
gameObject.StartTask(MyCoroutine());
IEnumerator MyCoroutine() { //this statement will move the execution to the background thread //pool. yield return Schedule.GotoBackground; //Do some work here //This statement will move the execution back into the main unity //foreground thread. yield return Schedule.GotoForeground; //When the coroutine is running in the main thread, yield statements //will work as normal. yield return null; yield return WaitForSeconds(1); }
Subscribe to:
Posts (Atom)
Popular Posts
-
These are the robots I've been working on for the last 12 months. They each weigh about 11 tonnes and have a 17 meter reach. The control...
-
This hard-to-see screenshot is a Generic Node Graph Editing framework I'm building. I'm hoping it can be used for any kind of node...
-
So, you've created a car prefab using WheelCollider components, and now you can apply a motorTorque to make the whole thing move along. ...
-
Unfortunately I've not secured a venue for the GGJ. With 9 days left, things are not looking hopeful. It could be that GGJ Perth will no...
-
Often, when building a game, you need to test if objects are colliding. The objects could be spaceships, rocks, mouse pointers, laser beams....
-
MiddleMan: A Pub/Sub and Request/Response server in Go. This is my first Go project. It is a rewrite of an existing Python server, based o...
-
Thank to Adrian Boeing I was inspired this morning to hack together a ripple shader for Unity3D. Thanks for the math Adrian. You can see th...
-
I made something which lets you render very large worlds with a small farClipPlane. https://github.com/simonwittber/scaled-origin The d...
-
I've just read a newspaper article (courtesy of Kranzky ) from WA Business News documenting the malfeasance, gross negligence and misc...
-
Space is awesome. Especially when it is generated using Perlin noise, and some cool shaders. You can try it out over here.