Posts Tagged unity

Unity Serializer v0.965 – RELEASE CANDIDATE 1


I am releasing the first release candidate of Unity Serializer. Thank you so much for all the help in testing.

[Fix] Removed more warnings concerning ScriptableObject instantiation
[Fix] Problems saving colliders in certain circumstances
[Fix] DoNotSerialize can target events
[New] IControlSerialization interface to allow components to specify that they should not be saved
[Fix] Joints were not storing motor and spring properties
[Fix] Rigidbodies weren’t always saving correctly in certain circumstances
[New] Getting started guide included in install
[New] iTween and PlayMaker packages included in AddOns folder
[Fix] Improved object activation
[Fix] Errors created by having duplicate prefabs (AddPrefabPath + normal)
[Fix] Problem with properties not always having a GetMethod (explicit interfaces?)
[Fix] Can now store terrain (so that it can be moved)

,

Leave a comment

Unity Serializer PlayMaker extension now has custom actions


I’ve added custom actions to the PlayMaker serializer to enable saving and resuming from checkpoints and also saving and loading games. There is an example scene in the download that shows using these actions to make a simple save game menu 100% in PlayMaker.

The download is available here.

, ,

Leave a comment

New Unity Serializer Getting Started Guide


I’ve added a longer Getting Started guide for Unity Serializer that you can access here.  I have also split out the API reference which is available on this page.

There will be an FAQ coming soon.

, ,

Leave a comment

Unity Serializer v0.951


Version 0.951 contains a series of fixes from inbound bug reports. No new features are expected

[Fix] Rigidbody no longer reports warning when kinematic
[Fix] Multiple similar components allowed on the same game object (broken in 0.941)
[Fix] Activation status of sub components could be overwritten
[Fix] Creation of scriptable objects caused a warning
[Fix] Wrapped UnityEditor using directive for builds

,

3 Comments

Unity, Vuforia & ZXing – Barcode scanning in AR games


I’ve been struggling with finding a good barcode scanner/QR code reader that works with Unity and doesn’t kill the framerate.  Given that I also have an AR application I thought that I would try to incorporate Vuforia with ZXing to get the best of both worlds and the good news is that it works pretty well and is very fast.  I’m attaching a download here of the package that contains a Unity friendly version of the C# port of ZXing together with my mulithreading manager Loom class.  Then here is an example of a script that will scan barcodes and/or QR codes and fire an event and send a message to a target object when something is decoded.

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System;
using System.Linq;
using com.google.zxing.qrcode;
using com.google.zxing.multi;
using com.google.zxing.common;
using com.google.zxing;
using com.google.zxing.client.result;

[AddComponentMenu("System/VuforiaScanner")]
public class VuforiaScanner : MonoBehaviour
{
	public QCARBehaviour vuforia;
	public bool barcode;
	public GameObject target;

	public static event Action<ParsedResult, string> Scanned = delegate {};
	public static event Action<string> ScannedQRCode = delegate {};
	public static event Action<string> ScannedBarCode = delegate {};

	bool decoding;
	bool initGray;
	MultiFormatReader mfReader = new MultiFormatReader();
	QRCodeReader qrReader = new QRCodeReader();

	void Update()
	{
		if(vuforia == null)
			return;
		if(vuforia.enabled && !initGray)
		{
                     //Wait 1/4 seconds for the device to initialize (otherwise it seems to crash sometimes)
		     initGray = true;
		     Loom.QueueOnMainThread(()=>{
	                      initGray = CameraDevice.Instance.SetFrameFormat(Image.PIXEL_FORMAT.GRAYSCALE, true);
		     }, 0.25f);
		}
		if (vuforia.enabled && CameraDevice.Instance != null && !decoding)
		{
			var image = CameraDevice.Instance.GetCameraImage(Image.PIXEL_FORMAT.GRAYSCALE);
			if (image != null)
			{
				decoding = true;

				Loom.RunAsync(() =>
				{
					try
					{
						var bitmap = new BinaryBitmap(new HybridBinarizer(new RGBLuminanceSource(image.Pixels, image.BufferWidth, image.BufferHeight, true)));
						Result data;
						if (barcode)
						{
							var reader = new MultiFormatReader();
							data = reader.decode(bitmap);
						}
						else
						{
							var reader = new QRCodeReader();
							data = reader.decode(bitmap);
						}
						if (data != null)
						{
							Loom.QueueOnMainThread(() => {
								if (data.BarcodeFormat == BarcodeFormat.QR_CODE)
								{
									ScannedQRCode(data.Text);
									if(target != null)
									{
										target.SendMessage("ScannedQRCode", data.Text, SendMessageOptions.DontRequireReceiver);
									}
								}
								if (data.BarcodeFormat != BarcodeFormat.QR_CODE)
								{
									ScannedBarCode(data.Text);
									if(target != null)
									{
										target.SendMessage("ScannedBarCode", data.Text, SendMessageOptions.DontRequireReceiver);
									}

								}
								var parsedResult = ResultParser.parseResult(data);
								if(target != null)
								{
									target.SendMessage("Scanned", parsedResult, SendMessageOptions.DontRequireReceiver);
								}
								Scanned(parsedResult, data.Text);
								decoding = false;
							});
						}
					}
					catch (Exception e)
					{
						decoding = false;
					}
				});

			}

		}
	}

}

, , , ,

5 Comments

Inheritable RPC Calls for Unity



Download

If you use RPC calls in Unity you sometimes want to be able to call an RPC defined on a base class and not overridden in a derived class.  This isn’t normally possible and leads to some complicated workarounds, so I’ve written an extension that allows you do do it generically.

Having installed the package you will be able to do networkView.RPCEx(…) and such calls will be routed to base class members.  The only requirements are:

  • The game object that is to receive these calls needs to have an InheritableRPC script attached to it
  • You cannot pass NetworkPlayer and NetworkViewID by these calls

You can however use this RPCEx method to pass parameters that are of any serializable class type – you are not limited to the usual list of simple parameters offered by Unity’s standard RPC methods.

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System;
using System.Linq;
using Serialization;

public class SomeBaseClass : MonoBehaviour
{
	[RPC]
	protected void PrintThis(string text)
	{
		Debug.Log(text);
	}
}

[AddComponentMenu("Tests/Inherited")]
public class Inherited : SomeBaseClass
{

}

Using normal RPC you couldn’t call PrintThis on something that had the Inherited script attached, with RPCEx you can

From Unity Script you would need to call the RPCEx like this:

       InhertiableRPCExtensions.RPCEx(networkView, routineName, mode /* e.g. RPCMode.All */, parameter1 /* Any number of parameters */, parameter2);

, ,

Leave a comment

Who Killed Who – Multicolor scrolling Unity Messages


Hey here’s my script for multi-color scrolling Who Killed Who messages.

Installation

Download the package and import it.  You are going to want to modify this file though, it contains examples.

In Use

Note the whole thing is driven off statics so you don’t need references you can just access the features through Messages.Message from your script.

Configuration

  • Configure the screen location you want by changing Messages.Message.messageStartPosition either in the code or at runtime. Note: start positions will be rounded to a multiple of verticalSpacing on start up. If you move it, perhaps to account for screen resolution, make sure that it is a multiple of verticalSpacing or the results will not be pretty.
  • Set the Y coordinate where fades will start irrespective of time. It’s Messages.Message.fadeY
  • Set the spacing of messages. Messages.Message.verticalSpacing
  • Choose your GUI skin/style for Label in the OnGUI call.

Displaying a Message

To display a message:

  • Call Messages.Message.QueueMessage(“Your message”); from any script
  • Messages support multiple color strings by using some custom formatting in the string:
  • Either a plain string or red,green,blue:My string|red,green,blue:Another string

You can have any number of those combinations: an example is “1,0.4,0.5:Hello |1,1,1:World”

  • You can also display a multi colour string from any OnGUI by using

Messages.Message.DrawGuiString(message, position)

Where position is a Vector2

I’ve included some examples to see it working…

, , ,

Leave a comment

.NET 2.0 Unity WeakTable – Store extended variables against anything


Sometimes you need to store variables next to something that you don’t own! This happens quite a lot in Unity, especially when working with things like NetworkPlayer – you want to associate something with an instance, but you don’t control the lifetime of that instance. Or you want to associate something with a GameObject, but you don’t want to add a script.

In .NET 4 you get support for this stuff already, using a WeakTable – a kind of dictionary that has elements whose lifetime is controlled by the lifetime of the items they reference. .NET 2 doesn’t have this built in by default – but I’ve written a replacement.

This technique will work from Javascript and C#, but the code has to be in C# hence I’ve built it as a plugin unity package you can download from here.

You use it like this (clearly this is an example, I could just modify test!):

//Javascript

//You can have any number of these type of classes
class MyExtendedProperties
{
    //Any number of members
    public var aProperty : String;
}

//This is a test class for this example
//try to believe that it's an object that we've
//got that we can't change the source of
class test
{
    //This is just so that there is something there
    public var test: String = "Hello";
}

function Start () {
    //Create a new instance of test
    var o = new test();
    //Give it an extra property in a new instance of MyExtendedProperties
    Extension.Get.<MyExtendedProperties>(o).aProperty = "World";
    //Read it back
    Debug.Log(Extension.Get.(o).aProperty);

    //Next time the garbage collector runs our extended properties will be cleaned up
    //as nothing has a reference to o
}

The C# is probably pretty obvious from that Javascript apart from the fact that the .Get method is an extension method callable in C# like this

anythingAtAll.Get<MyExtendedProperties>().aProperty = "cool huh";

So the basic idea it to have a dictionary, keyed off the object that contains another class that you can put extra information in. The problem of just doing this straight off is that the fact that the object is the key will keep the object alive forever – read massive memory leaks if this gets used too widely. The answer to that is to use weak references and get a notification when the garbage collector runs to enable you to clean up the extra instances associated with objects that have been killed.

, , ,

Leave a comment

100% Free Unity Serialization – Load & Save game


UnitySerializer is a full level serialisation plug in.  It enables you to save the progress of a game and restore it at some point in the future.  It does this with minimal impact on the design of your game and requires minimal modification to your behaviours and classes.

UnitySerializer has been tested working on iOS and should work fine on Droid.

The serializer supports storing newly instantiated prefabs, as well as the status of existing scene objects (such as those that might be destroyed during the course of a game).

UnitySerializer supports the serialization of your custom classes and properties as well as standard Unity components

  • Animation support
  • Rigidbody support
  • Support for NavMeshAgent (although the agent must recalculate its path on restoration)
  • Transform – including parent/child relationships
  • Important: UnitySerializer cannot store the current state of an iTween at present, due to the way in which iTween works.  If you need path following you can use the code found elsewhere on this blog which will resume fine.
In addition, presuming you use my extended coroutine start functions, all of your coroutines will continue executing from the point that they left off and will be restored with all local variables intact. You need make no changes to your coroutines – just to the way that you start them.

The status of your level is stored in a string which can be placed in PlayerPrefs – stored on a server or in a file.

UnitySerializer has its own page here.

, , , , ,

Leave a comment

Faster Invoke for reflected property access and method invocation with AOT compilation



Download

The bane of the iOS programmers life, when working with reflection in Mono, is that you can’t go around making up new generic types to ensure that your reflected properties and methods get called at decent speed. This is because Mono on iOS is fully Ahead Of Time compiled and simply can’t make up new stuff as you go along. That coupled with the dire performance of Invoke when using reflected properties lead me to construct a helper class.

This works by registering a series of method signatures with the compiler, so that they are available to code running on the device. In my tests property access was 4.5x faster and method access with one parameters was 2.4x faster. Not earth shattering but every little helps. If you knew what you wanted ahead of time, then you could probably do a lot better. See here for info.

You have to register signatures inside each class I’m afraid. Nothing I can do about that.

So to register a signature you use:

static MyClass()
{
     //All methods returning string can be accelerated
     DelegateSupport.RegisterFunctionType<MyClass, string>();         
     //All methods returning string and taking an int can be accelerated
     DelegateSupport.RegisterFunctionType<MyClass, int, string>();    
     //All methods returning void and taking a bool can be accelerated
     DelegateSupport.RegisterActionType<MyClass, bool>();             

}

Then when you have a MethodInfo you use the extension method FastInvoke(object target, params object[] parameters) to call it. FastInvoke will default to using normal Invoke if you haven’t accelerated a particular type.

       myObject.GetType().GetProperty("SomeProperty").GetGetMethod().FastInvoke(myObject);
       myObject.GetType().GetMethod("SomeMethod").FastInvoke(myObject, 1, 2);

You can download the source code for FastInvoke from here.

, , , , , ,

Leave a comment

Fixing the width of strings displayed in the Unity GUI


Firstly, I know what you are going to say – you should just use two aligned labels, rather than fiddling around with string formatting – but sometimes that just doesn’t work – like when you want the items in a popup to have columns like here:

No chance for using labels in that component.  So there is a way of effectively padding text to a given width.  You basically work out the width of a ” “, a tab and the string, then use that combination to make a new string which is the correct width.

Just using string.PadRight(20) doesn’t work due to the variable width of characters in the font.


public static class TextHelper
{
	public static string FixTo(this string str, float width, string type="label")
	{
	    var widthOfTab = GUI.skin.GetStyle(type).CalcSize(new GUIContent("\t")).x;
		var widthOfSpace = GUI.skin.GetStyle(type).CalcSize(new GUIContent(" ")).x;
		var widthOfString = GUI.skin.GetStyle(type).CalcSize(new GUIContent(str)).x;
	    return str + new String(' ', (int)((width-widthOfTab)/widthOfSpace)+1) + "\t";
	}
}

You basically use myString.FixTo(150) to fix it based on the width of a “label” in the skin or you can override it to set a different font by using myString.FixTo(200, “box”).

Should work fine in javascript so long as you make a .cs file out of this and put it in your plugins folder.

, , , ,

1 Comment

Extended Unity Coroutines



If you’ve downloaded Unity Serializer you have an updated version of this already Download

I really like the coroutine pattern in unity but unfortunately it’s not possible to directly extend it. What I would really like is to be able to write cut scene and NPC logic in a single routine, but I need to do things like wait for an animation to complete or an AI task goal to be achieved. Not being able to write my own YieldInstructions I took to the keyboard and wrote an extended coroutine system that uses as Unity’s existing stuff as a base.

To use it you can download and install the package, then when you want to start an extended coroutine you use:

StartCoroutine( RadicalRoutine.Run(yourEnumeratorFunction()) )

YOU MUST insert the RadicalRoutine.Run inside the StartCoroutine call or not much will happen!

Note it only works with the none “text” based version of StartCoroutine at the moment.

Now you can write your own classes that indicate the completion status, they inherit from CoroutineReturn and can set or override two key values.

  • finished – set to true / or override and return true when the action has finished
  • cancel – set to true / or override and return true if you want the whole coroutine to be aborted

I’ve included one that waits for a part of an animation (end or some point in the middle) to complete and a version that waits for the weight of some animation to reach a value (I use this to keep my blended animations smooth in cut scenes). It’s called WaitForAnimation and there’s an extension class that adds methods to GameObject: gameObject.WaitForAnimation(name, normalizedTime /* default 1f */) and gameObject.WaitForAnimationWeight(name, weight /* default 0f */);

You can also yield any standard Unity YieldInstruction like WWW, WaitForSeconds etc.

You can use the coroutine functions from c# or javascript.

Example

Here’s an example of me using the extensions to run a complete sequence for an NPC. Obviously in this example I’m calling routines in my game that aren’t listed, but they all return CoroutineReturn instances that pause execution until the task is complete. You can see me using the WaitForAnimation and WaitForAnimationWeight methods directly.

What I want to do is move my character over to a table, pick up an envelope, show it to the player and then put it back down again afterwards.

	IEnumerator MoveToPosition_EnterState()
	{
		Vector3 envAngle;

		//Store the current position of the envelope to be picked up
		var rot = msg.transform.rotation;
		var parent = msg.transform.parent;
		var pos = msg.transform.position;
		//Find the point that will carry the envelope
		var ch = gameObject.GetComponentInChildren();

		//Move the character to the envelope's location
		yield return MoveTo((lookPt = msg.transform.Find("EnvelopeLook")).position);
		//Look at the envelope
		yield return RotateTo(envAngle = lookPt.rotation.eulerAngles);
		yield return new WaitForSeconds(0.3f);
		//Play the pickup animation
		Animate("pick_up_from_table");
		//Wait until half way through
		yield return gameObject.WaitForAnimation("pick_up_from_table",0.5f);

		//Put the envelope in the carry point
		msg.transform.parent = ch.transform;
		msg.transform.localPosition = Vector3.zero;
		msg.transform.localRotation = Quaternion.Euler(0,0,0);

		//Wait for the pickup animation to complete
		yield return gameObject.WaitForAnimation("pick_up_from_table");

		yield return new WaitForSeconds(0.2f);
		//Turn to face the camera
		yield return RotateTo(new Vector3(0,10,0));
		//Wait for the rotation animations to complete
		yield return gameObject.WaitForAnimationWeight("left_turn"); //Without a specified second parameter waits for 0
		yield return gameObject.WaitForAnimationWeight("right_turn");
		//Play the excited animation
		yield return Animate("excited");
		yield return new WaitForSeconds(0.5f);
		//Raise the hand containing the envelope
		yield return Animate("hand_raising");
		yield return new WaitForSeconds(1.5f);
		yield return Animate("hand_raising");
		yield return new WaitForSeconds(2.5f);
		//Wave move dramatically
		yield return Animate("waving");
		yield return new WaitForSeconds(0.5f);
		//Turn around to face the table
		yield return RotateTo(envAngle);
		//Play the pickup animation
		Animate("pick_up_from_table");
		//Wait for it to be 40% complete
		yield return gameObject.WaitForAnimation("pick_up_from_table",0.4f);
		//Put the envelope back on the table
		msg.transform.parent = parent;
		msg.transform.position = pos;
		msg.transform.rotation = rot;
		//Wait for the animation to complete
		yield return gameObject.WaitForAnimation("pick_up_from_table");
		//Rotate to face the camera
		yield return RotateTo(new Vector3(0,10,0));
		//Look over shoulder at envelope
		yield return Animate("looking_behind");
		//Sigh
		yield return Animate("relieved_sigh");
		yield return new WaitForSeconds(1);
		//Finish activity
		BlackboardComplete();

	}

Additional

You can also call RadicalRoutine.Create(yourCoRoutineFunction()) which returns an RadicalRoutine instance that can be cancelled. To use that you pass the instances enumerator property to StartCoroutine like this:

r = RadicalRoutine.Create(myRoutine());
StartCoroutine(r.enumerator);

r.Cancel(); //Abort on the next iteration

Also the RadicalRoutine has events for cancellation and completion called Cancelled and Finished.

, , , ,

Leave a comment

Unity curved path following with easing at constant speed



Download

The Problem

I have a character than needs to follow paths curved through a series of control points as it moves around the world. I also want to ease in and out to speed of movement as the path starts and ends. Sometimes in the middle of a path follow I need to change my mind and have some other path taken or perhaps change from path following to another state. This isn’t possible with iTween at constant speed unless you use PutOnPath, which doesn’t allow easing functions. I would also like to be able to move at a constant speed – either by ignoring the length of individual path elements (and thereby specifying at time fraction for the whole path) or by having a maximum speed my object can travel at.

Solution

Building on the great work done by Andeeee and Renaud, I’ve made a path following class that enables you to specify from 2 to N points and have it build a curved path (if it has more than 2 points!), you can then follow that path using a time from 0…1 and also apply an easing function to make the start and the end points smooth.

It supports Linear, Sine, Quadratic, Cubic, Quintic and Quartic easing functions with control on over whether the path is eased in and out separately.


Line 1 – EaseIn, Line 2 – EaseOut, Line 3 – EaseIn and EaseOut

This allows fine grained control of an eased, spline path in an Update function that is not possible using iTween – this enables you to abort a movement halfway through if something more important is happening .

To use it you download and import the unity package.

Eased spline paths

To use no easing call Spline.Interp(arrayOfPoints, time). Where time is a float between 0 and 1.

The array of points can be an array of Vector3s, GameObjects or Transforms which are implicitly converted to a Spline.Path instance containing an array of Vector3s. DON’T BOTHER to create your own Spline.Path instances!

e.g. transform.position = Spline.Interp(myPathObject.GetComponentsInChildren<Transform>(), time);

This would use the myPathObject and all of its children to define the path. (For example only, don’t go calling GetComponentsInChildren every frame).

To ease the function you can supply one or more of the easing parameters:

Spline.Interp(arrayOfPoints, time, easingType /* e.g. EasingType.Sine */, easeIn /* e.g. true (default) */, easeOut /*e.g. false (default true) */ );

The Spline class also supports Andeeee’s Velocity and GizmoDraw functions to help you with debugging.

PLEASE NOTE: the function uses a different algorithm for short paths so that you can get a number of different effects. If your path has 2 points it does a linear interpolation, 3 points does a Quadratic spline and 4 points does a Cubic spline. The 5 or more point version uses Catmul Rom splines and ensures that the path passes through every point.

You can double up start and end points easily with the Spline.Wrap() call on your path array – you may want to do this for short paths if you want to ensure that all of the points are passed through – or just do it yourself. There should be no effect if you are using InterpConstantSpeed or MoveOnPath when you do this (See below).

Constant Speed

I’ve added an InterpConstantSpeed function too, this tries to make the speed of movement constant between sections. It works in the same way as Interp, with a time value between 0 and 1.

Now just a note on that.  If your path points are moving then you need to watch constant speed interpolations as one section getting much longer or shorter could cause the position to vary wildly.  If your path sections are increasing or decreasing in size then you are better off using Interp and trying to make sure that each path section is roughly the same size (short sections will appear to have lower velocity than large sections, so they need to be “kind of” the same size).  Interp says if your path has 5 sections, each one takes 1/5 of the time to cross.  If you are in section 2 and section 3 gets bigger, you will complete section 2 in the normal time.  Using constant speed, the position at time “t” is along the magnitude of the whole path, if it gets longer or shorter then the position at “t” will change between sections moving the Vector unrealistically forwards or backwards. This is a problem if you are in an early stage of the path and a later path point, far off screen, is moving.  The Vector will stutter for apparently no reason.  If you want constant speed then you need to ensure that your path points maintain exactly the same distance from each other when they move (they need to move in an arc centered on the previous end point).

The second point is that applying “Constant Speed” and “Easing” appears to create a paradox; but InterpConstantSpeed accepts easing functions! Well the “Constant” bit refers to the sizes of path sections being converted to a path magnitude and the easing is applied to the “time” fed into the path calculator: so you can have your cake and eat it 🙂

Path Movement and Character Speed

I’ve also added a speed limited version, this also solves the constant speed issue by having a maximum possible movement speed, you can therefore move those path elements as often as you like – but you can’t specify the time it takes to complete the path. It works kind of like a SmoothDamp – here’s how you go about it:

public class TestFollow : MonoBehaviour {

	public Transform[] path;

	float t = 0;

	// Update is called once per frame
	void Update () {
		transform.position = Spline.MoveOnPath(path, transform.position, ref t, 0.5f);

	}
}

Basically you pass the path, the current position and a reference to a float that will contain the currently targeted path point, the final parameter shown here is the number of world units per second to move.

This routine also has the added benefit that it will move to the start of the path before following it.

Here are all of the parameters to MoveOnPath:

Parameter Meaning
pts An array of transforms, Vector3s or GameObjects that describe the path
currentPosition The current position of the object being moved
pathPosition The position along the path, this is updated by the call so must be a variable of the class
(Optional)rotation A quaternion that will be updated to show the rotation that should be used. This can change quickly for slow moving objects, so you might want to smooth it. See below.
maxSpeed The maximum number of world units to move in one second, default is 1
smoothnessFactor The smoothing factor is the number of steps on the path that will be used, default is 100
ease The type from EasingType.Linear, EasingType.Sine, EasingType.Cubic, EasingType.Quadratic, EasingType.Quartic and EasingType.Quintic. Default is Linear
easeIn true if you want to ease in the function or false if you don’t. Default is true
easeOut true if you want to ease out the function or false if you don’t. Default is true

Here’s an example of the version that returns a rotation, in this example I use the SmoothQuaternion from a previous post to smooth out the rotations.

#pragma strict

var pathPoints : Transform[];

var t : float;
var sr : SmoothQuaternion;

function Start() {
	sr = transform.rotation;
	sr.Duration = 0.5f;
}

function Update () {
	var q : Quaternion;
	transform.position = Spline.MoveOnPath(pathPoints, transform.position, t, q, 0.5f, 100, EasingType.Sine, true, true);
	sr.Value = q;
	transform.rotation = sr;

}

Javascript

You can use the Spline class from JavaScript, as long as the .cs files are somewhere inside a Assets/Plugins folder (the download does this) and that JavaScript is not inside a Plugins folder.

This example will follow a constant speed path for 20 seconds.

#pragma strict

var pathPoints : Transform[];

var t : float;

function Update () {
	transform.position = Spline.InterpConstantSpeed(pathPoints, t, EasingType.Sine, true, true);
	t += Time.deltaTime/20;
}

The next one moves an item on a path at a maximum of 0.5 world units per second

#pragma strict

var pathPoints : Transform[];

var t : float;

function Update () {
	transform.position = Spline.MoveOnPath(pathPoints, transform.position, t, 0.5f, 100, EasingType.Sine, true, true);

}

, , , , , , ,

37 Comments

Smoothed Vector3, Quaternions and floats in Unity



Download

I’ve put together a set of structs to handle changing the values of floats, Vector3s and Quaternions over time. It’s very simple to use and is far easier to read than having lots of time recognising code or referenced veclocities in the middle of your game logic. You replace a Vector3 (say) with a SmoothVector3 in your code, set its target value, smoothing method and duration, then read its value over time in an Update() call. I use this when I don’t have a gameObject to hand to apply iTween or when I may want to keep changing the position and don’t want to mess with iTween and need the control at every Update call.

You can choose a smoothing mode from slerp, lerp, SmoothDamp and SmoothStep.

To use this in your code, download the .cs file and put it in your Assets/Plugins folder.

Here is an example from JavaScript on how to use the SmoothVector3 to smoothly move an object when a key is pressed.


#pragma strict

var pos : SmoothVector3;

function Start () {
	//Construct a SmoothVector3 by assigning a normal Vector3
	//this initializes the position
	pos = transform.position;

	//The following are optional and override the standard settings

	//Duration in seconds of the transform
	pos.Duration = 1;
	//Smoothing mode from damp, smooth, lerp and slerp
	pos.Mode = SmoothingMode.damp;
}

function Update () {
	if(Input.anyKeyDown)
	{
		//Setting the Value of the SmoothVector3 starts the interpolation
		//This will move the item 1 unit in X,Y from the current position
		//(which may be an interpolated value)
		pos.Value = pos.Value + Vector3(1,1,0);

		//In this example this is equivalent to
		//pos.Value = transform.position + Vector3(1,1,0);

		//An alternative is to use the .Target property
		//which is the current targeted position - in our example
		//this maintains the object on exact boundaries and means
		//that it will accelerate if you click lots of times
		//pos.Value = pos.Target + Vector3(1,1,0);

		//Or of course you could just set the value
		//pos.Value = Vector3(100,100,0);

	}

	//A SmoothVector3 can be used in place of a Vector3 in assignments
	transform.position = pos;

}

With Vector3 and Quaternions you can directly affect the individual elements to set the targeted value.

       mySmoothVec3.x = mySmoothVec3.x + 100;

, , , , , , ,

1 Comment

Unity terrain avoiding smart follow camera



Download

I’ve been needing a terrain avoiding follow camera, I couldn’t find one that was exactly right so I produced my own.

My script uses multiple different methods to keep the followed object in view:

* Desired location with the camera adjusted for terrain height

* Rise above structures

* Zoom in to be closer to the followed object

* Camera rotation (cut view) to a different angle

Each method can be weighted to give the effect that you prefer.  Each method votes on how aggressive a movement it had to make in order to locate the camera in an unobstructed location, the winner gets to set the location of the camera.

You can download it here.

Here is it in operation – I’m moving the camera a bit to put it in difficult places, but mostly it’s under the control of the system.

, , ,

2 Comments

Unity automatic MeshCollider generation


When ever I get a model that has many sub elements, but no standard mesh colliders I use the wizard listed here to automatically generate them.  Thought it might come in useful to others…


using UnityEngine;
using UnityEditor;
using System.Collections;
using System.Linq;
public class AddColliders : ScriptableWizard {

 [MenuItem("Wizards/Add Mesh Colliders")]
 static void CreateWizard()
 {
    ScriptableWizard.DisplayWizard<AddColliders>("Add mesh colliders", "Add Colliders");
 }

 void OnWizardCreate()
 {
    if(UnityEditor.Selection.activeGameObject != null)
    {
       foreach(var c in UnityEditor.Selection.activeGameObject.GetComponentsInChildren<MeshRenderer>().Cast<MeshRenderer>().
       Where(mr=>mr.GetComponent<MeshCollider>()==null))
       {
           c.gameObject.AddComponent(typeof(MeshCollider));
       }
    }
 }
 void OnWizardUpdate()
 {
    helpString = "Add mesh colliders to all items that have a mesh renderer";
 }

}

, , ,

Leave a comment