SecretAsianMan

Unity Tutorials

Recommended Posts

Learning how to use the physics engine to move stuff isn't all that difficult, but just a warning: Box2D is deterministic, but only on a per-hardware basis. There's no guarantee the movements will be the same across different machines. This largely only shows itself in floating point errors, so in most cases it's so small that it's not noticeable, but it's worth keeping in mind if you're doing anything super complex. With lots of object interaction.

 

For pure movement, if the ships/whatevers won't actually collide with anything besides the player ship and bullets, it's probably fine.

 

Also for purposes of moving ships around in a shmup, I personally probably wouldn't touch forces. I'd just straight set the velocity and let it go, or change it based on what kind of pattern you want.

 

Velocity is probably what I should have said, yeah.

Share this post


Link to post
Share on other sites

Attractors is an interesting idea... I'm going to look into that I think.

 

I told my dancers where to stand using invisible gameobjects that I switched between sets of. I could have just as easily moved them around though. Here's the script, it might help you visualize how it would go down. You can use any part of it that you want. The parts you would be most interested in are the assignments of numbers to the dancers in the initialization portion, the MoveToPosition(), ChooseTarget(), and SwitchPosition() methods. 

 

using UnityEngine;
using System.Collections;

public class AssignedPositions : MonoBehaviour {

//For assigning ints to each dancer.
	public static int npcCount;
	int npcNumber;
	
	Transform _transform;

//Here are the dance formations. They are empty parents with four empty gameObjects as children that act like baseball bases.
	public GameObject largeSquare;
	Transform[] largeSquares= new Transform[4];
	public KeyCode largeSquareKey;

	public GameObject smallDiamond;
	Transform[] smallDiamonds=new Transform[4];
	public KeyCode smallDiamondKey;

	public GameObject horizontalLine;
	Transform[] horizontalLines=new Transform[4];
	//This must be assigned because I use the none value.
	public KeyCode horizontalLineKey;

	//This allows me to check to see if the new keycode is the same as the old one so that it won't do it a million times when it's pressed down.
	KeyCode currentKeycode;
	
	//Since horizontal lining is assigned to a key combination it needs more stuff
	//Whether or not it is currently in that formation
	bool horizontalLining;
	//An optional key.
	public KeyCode switchPositionKey;

	//Because switching positions isn't assigned to a particular key, I have to make it a switch.
	bool switchingPosition;


	//My first enum. I forgot this was here. determines what's happening with the accordion.
	enum PushPull {still, pushing, pulling};
	PushPull pushPull_this=PushPull.still;
	
		
	//Taking account of the gameObjects that make the danceFormation bases.
	Transform target_transform;
	//An array of the current formation
	Transform[] currentTarget_array;
	Vector3 targetLocation;
	
	bool targetReached;

//Dancer attributes
	//Speed of dancers.
	float speed;
	public float minSpeed=0.6f;
	public float maxSpeed=1;

	//This is for flipping the sprite
	Vector3 rotationRight;
	Vector3 rotationLeft;

	Animator animator;

	//Giving them various pushiness
	Rigidbody2D theRigidbody2d;
	float startingMass;

	//A timer to reposition when pushed out of way.
	float repositionTimer=0f;
	//How many times they can try to reposition themselves.
	int attemptsLeft;


//Wandering. This doesn't apply to when they are dancing. This is their idle state.
	GameObject wanderTarget;
	bool wandering;
	//Once they get there they stand there for a moment.
	bool waitingToWander;
	float wanderTimer=0f;
	float wanderCycle=1;
	

//---------------------------------------------------------------------------------------------------------
//Here are the methods.
	void Awake()
	{
		//Assign each dancer a number.
		npcNumber=npcCount;
		npcCount=npcCount+1;
		
		//Create a target for them to wander to, it will be placed later.
		wanderTarget=new GameObject();
	}
	
//This assigns the bases of each dance formation into an array of Transforms.Dance formations are organized in the inspector as an empty parent with the bases being their children.
	void GetPositionList(GameObject positionGroup, Transform[] positionArray)
	{
		//Get Transform of the formation (parent)
		Transform positionGroup_transform=positionGroup.GetComponent<Transform>();
		int loopCounter=-1;
		//Fill an array for each with all the children's transforms. 
		foreach(Transform child in positionGroup_transform)
		{
			loopCounter=loopCounter+1;
			positionArray[loopCounter]=child;
		}
	}

	void Start () 
	{
		_transform=this.GetComponent<Transform>();
		
		//Assign each formation's children to their arrays.
		GetPositionList(largeSquare, largeSquares);
		GetPositionList (smallDiamond, smallDiamonds);
		GetPositionList(horizontalLine, horizontalLines);

		//Dancer speed is procedurally generated
		speed=Random.Range (minSpeed, maxSpeed);

		//Rotations I want the sprites flipped to when walking to the right or left.
		rotationRight=_transform.rotation.eulerAngles;
		rotationLeft=rotationRight;
		rotationLeft.y=180;

		animator=this.GetComponent<Animator>();

		//Kinda a hack solution to make some of them more pushy than others
		theRigidbody2d=this.GetComponent<Rigidbody2D>();
		startingMass=Random.Range(1, 9);
		theRigidbody2d.mass=startingMass;

		

		//This makes it so I can pretend that their first wandering state came after a moment of waiting like all others.
		//They start in a wandering state.
		targetReached=true;
		wandering=true;
		waitingToWander=false;
	}
	

	void Wander()
	{
		if (targetReached)
		{
		//If they find their target, I want them to wait a bit.
			if(waitingToWander==false)
			{
				//How long they will wait once they reach their target.
				wanderCycle=Random.Range(1f, 4f);
				waitingToWander=true;
			}
			if (waitingToWander)
			{
				//Debug.Log ("NPC "+npcNumber+" is waiting" + wanderTimer+" of " +wanderCycle);
				wanderTimer=wanderTimer+Time.deltaTime;
				if(wanderTimer>wanderCycle)
				{
					//reset everything
					targetReached=false;
					waitingToWander=false;
					wanderTimer=0f;
					
					//Put their wander target somewhere.
					wanderTarget.transform.position= new Vector3(Random.Range(-8f, 8f), Random.Range(-5f, 0f), 0f);	
					//Make the wanderTarget their target that can be applied to Move()
					target_transform=wanderTarget.transform;
					//Just in case it's off...
					wandering=true;

					//I'd also like them to put their arms back down.
					LowerArms();
				}
			}
		}
	}
	
	void LowerArms()
	{
		animator.SetBool ("rightArmLift", false);
		animator.SetBool("rightArmLower", true);
		animator.SetBool ("leftArmLift", false);
		animator.SetBool("leftArmLower", true);
	}

	void MoveToPosition()
	{
		if (!targetReached)
		{
			animator.SetBool ("walking", true);
			
			//Straight up, move towards a target at the step increment.
			float step=speed*Time.deltaTime;
			_transform.position=Vector3.MoveTowards(_transform.position, target_transform.position, step);
			
			//This is to mirror the sprite image if they are walking left
			if (_transform.position.x<target_transform.position.x)
			{
				_transform.rotation=Quaternion.Euler (rotationRight);
			}
			else 
			{
				_transform.rotation=Quaternion.Euler (rotationLeft);	
			}

			//reset mass after they were able to be pushed.
			theRigidbody2d.mass=startingMass;
			
			//Check to see if it has reached the target.
			if(_transform.position==target_transform.position)
			{
				targetReached=true;
				animator.SetBool ("walking", false);
				//Making it so that others can push them out of the way to get in their place
				theRigidbody2d.mass=0f;
				wandering=true;
				//attemptsLeft is assigned by ChooseTarget(), so I can use this to see if they were recently assigned a position.
				if(attemptsLeft==2)
				{
					//Give them a longer amount of time that they are willing to wait once the target is reached.
					wanderCycle=Random.Range (10, 30);	
					waitingToWander=true;
				}
			}
		}
		//Reposition if knocked out of position
		if((targetReached)&&(_transform.position!=target_transform.position))
		{
			repositionTimer=repositionTimer+Time.deltaTime;
			if ((attemptsLeft>0)&&(repositionTimer>1f))
			{
				repositionTimer=0f;
				targetReached=false;
				MoveToPosition();
				attemptsLeft=attemptsLeft-1;
				//Debug.Log ("repositioning");
			}
		}
	}
	
	//The dancer chooses the base of the formation that matches their number.
	void ChooseTarget(Transform[] positionList)
	{	
		//Resets
		targetReached=false;
		attemptsLeft=2;
		wandering=false;

		//Keep a record of what formation you are part of in case SwitchPosition() is called.
		currentTarget_array=positionList;
		
		if(npcNumber<=positionList.Length-1)
		{
			target_transform=positionList[npcNumber];
		}
	}

	//Everybody switch your assigned numbers.
	void SwitchPosition()
	{
		if(npcNumber==npcCount-1)
		{
			npcNumber=0;
		}
		else
		{
			npcNumber=npcNumber+1;
		}
		//Refresh the target now that you have a new number.
		ChooseTarget(currentTarget_array);
	}

//Getting out of the horizontal line is particularly sticky so I need to call the request for the other positions when it happens.
//So I'm going to put them in a method that Update() will call.
//Edit: I fixed it, the problem was that I was checking for !largeSquare&&smallDiamond rather than !(largeSquare&&smallDiamond)
	void CheckForPositionInput()
	{
		if(ChangeWidth.changeInLength!=0)
		{
			
			if (currentKeycode==horizontalLineKey)
			{
				if (!((Input.GetKey(largeSquareKey))&&(Input.GetKey(smallDiamondKey))))
				{
					currentKeycode=KeyCode.None;	
				}
			}
			if (currentKeycode!=largeSquareKey)
			{	
				if(Input.GetKey(largeSquareKey)&&(currentKeycode!=horizontalLineKey))
				{
					currentKeycode=largeSquareKey;
					ChooseTarget(largeSquares);
					Debug.Log(currentKeycode);
				}
			}
			if (currentKeycode!=smallDiamondKey)
			{
				if (Input.GetKey(smallDiamondKey)&&(currentKeycode!=horizontalLineKey))
				{
					currentKeycode=smallDiamondKey;
					ChooseTarget(smallDiamonds);
					Debug.Log(currentKeycode);
				}
			}
			
			if (currentKeycode!=horizontalLineKey)
			{
				if (Input.GetKey(smallDiamondKey)&&(Input.GetKey (largeSquareKey)))
				{
					currentKeycode=horizontalLineKey;
					//I had to set the currentKeycode to an arbitrary value.It wouldn't have one because I use two keys for it, but I need to use the Keycode.None value later.
					ChooseTarget(horizontalLines);
					Debug.Log(currentKeycode);
				}
			}
		}
	}

// Update is called once per frame
	void Update () 
	{
		CheckForPositionInput();

		if(currentTarget_array!=null)
		{
			if((ChangeWidth.changeInLength>0f)&&(pushPull_this!=PushPull.pulling))
			{
				pushPull_this=PushPull.pulling;
				SwitchPosition();
			}
			
			if((ChangeWidth.changeInLength<0f)&&(pushPull_this!=PushPull.pushing))
			{
				pushPull_this=PushPull.pushing;
			}
		}
		if ((targetReached)&&(wandering))
		{
			Wander();
		}
		
		if (target_transform!=null)
		{
			MoveToPosition();
		}
	}
}

Share this post


Link to post
Share on other sites

Does anyone know if any of tutorials that are suitable for absolute beginners? Unity probably isn't the best place to start for learning to code but I know my way around it and can easily add non-code elements to projects but of course I'm open no non-unity tutorials, preferable C# though so I can easily transition to Unity.

Share this post


Link to post
Share on other sites

Does anyone know if any of tutorials that are suitable for absolute beginners? Unity probably isn't the best place to start for learning to code but I know my way around it and can easily add non-code elements to projects but of course I'm open no non-unity tutorials, preferable C# though so I can easily transition to Unity.

 

I learned to code making Unity games. So I think it's a great way to do it. 

Have you already done some of the Unity tutorials? I ask because you say you know your way around it. Are you looking for a Unity tutorial that is more coding-heavy?

Share this post


Link to post
Share on other sites

Does anyone know if any of tutorials that are suitable for absolute beginners? Unity probably isn't the best place to start for learning to code but I know my way around it and can easily add non-code elements to projects but of course I'm open no non-unity tutorials, preferable C# though so I can easily transition to Unity.

 

If you're an absolute coding beginner then I would start with codecademy.com to get the basics of coding in general (I'd start with javascript, personally). 

 

If you understand the basics of coding and thinking with that type of logic then grab a beginner tutorial from the asset store. I started with the space shooter tutorial, for example. I ripped through that quickly enough to get the basics of both C# and the Unity engine and rolled right over into my project.

Share this post


Link to post
Share on other sites

I don't think I've done any of the Unity tutorial from Unity, if I have it's been long enough that I'd have to re-do them :)

I ran through all of the codecedemy tutorials on to JS and did all of the pure JS ones but then it was branching off into areas away from games and I sorta lost interest. This was a couple of years ago though. I've been using Playmaker (a visual scripting plugin) for a few years and that's given me a better understanding of the logic but no understanding of the structure or syntax.

 

Also like others in the thread I'm not fond of video tutorials but I don't think I have a lot of choice. I guess I'll start doing the Unity3d.com ones.

Share this post


Link to post
Share on other sites

The Unity video tutorials are pretty great because they come with files to follow along. Also the guy doing the videos has a delightful accent. I liked starting with JS and then going to C# because of the way I learn, mostly. I was able forced to apply logical thinking across two languages with different syntax rather than rely on cut and paste methods to achieve goals.  I think my coding is stronger for it, but ymmv.

 

I can't speak to the individual quality of the Unity tutorials, because I've only done a couple. Though I think that the ones that are game/project specific, like the space shooter one, are better to start with than the general engine ones, like the 2d Unity one.

Share this post


Link to post
Share on other sites

I can second the space shooter tutorial; it was the first one I did. I worried too much about why the things are typed the way they are. Just do exactly as he says and then when you are finished You can try to do it from memory, but making changes to the code when you want to fiddle with it a bit (if that appeals to you). When you break something or forget how to do something, you can go back and watch that part of the tutorial again.

A simple tip:

Highlight a function in the script and press cmd and ' to go directly to the script reference which usually has c# available (look at the top right for an option to change language). The hard part for me was just not knowing what functions were available and what their synax was. I managed to get a lot done just highlighting functions in the script from the tutorial and retyping the examples in the reference.

Share this post


Link to post
Share on other sites

Thanks guys I'm starting to go through the roll a ball one and I'll move on to the space shooter afterwards. I do like it so far, it seems to be the perfect level of complexity for me, I just have to stop myself from typing while it's playing as I miss things that way :P

Share this post


Link to post
Share on other sites

Youtube has keyboard shortcuts. I think it's shift space for play/pause and shift leftArrow fto go back five seconds. Not sure if that is helpful though since you'll be in another window.

Share this post


Link to post
Share on other sites

Thanks that is actually quite useful.

One issue so far is versions, some of the tutorials are made for older versions of Unity and some things are different. With the space shooter for instance the way you access rigidbody components has changed but luckily unity has converted the 'done' versions so when I get compatibility issues I can just see what it did to update them.

Of course I could just get the right version but I'd rather learn the newest methods if I can.

Share this post


Link to post
Share on other sites

Unity Answers is a good supplement to the tutorials too:

 

http://answers.unity3d.com

 

It's basically a question and answer site, where you can get help if you're having trouble understanding parts of Unity. You can browse other people's questions, and if there's none that answer your question then you can make a new post and ask it. People are generally pretty helpful regardless of skill level (as long as you make the effort to follow their rules about making a question clear) so it's a good place to go if you need help solving a specific problem or you need to understand a function better.

Share this post


Link to post
Share on other sites

The space shooter tutorial was fun, mostly after I'd finished it and decided to add some things. I tried the survival shooter one but it seemed a bit rushed and was skipping over a lot of what the code does, so I quit that one. I also tried a cooking with unity one but I didn't really get on with it, again I enjoyed modifying it though.

 

I think I might just start making something and see how it goes, it's probably way too early but we'll see.

Share this post


Link to post
Share on other sites

If you get stuck please post about it. There is a lot of expertise on this forum. I'll help whenever I can.

Share this post


Link to post
Share on other sites

This is what I've spent the last day and half or so on: http://www.bretteveleigh.co.uk/other/Glider_Prototype.rar

It's stand alone because I tried a webgl build and it was pretty janky and normal web player is too much of a pain these days.

 

I was playing Gone Home and really liked just gliding around the environment so I figured that'd be a good exercise to try.

It's a lot rougher than I'd like, the biggest problem is limiting rotation in a way that doesn't feel harsh.

Share this post


Link to post
Share on other sites

Edit, nevermind, I figured it out 5 seconds after posting...

 

I was looking at that last night before leaving work, what did it end up being?

Share this post


Link to post
Share on other sites

I'd got it the wrong way around, I was trying to reset the camera when there was no input so it was 'input != 0' when it should have been 'input == 0'. I think I was confusing the input variables with the ones measuring current properties, so it the current rotation (or whatever) is anything other than 0 then do something.  It was one of those things that's totally obvious but for some reason you look at it at the time and think "No that's fine, I wonder what's wrong" :)

Share this post


Link to post
Share on other sites

This is what I've spent the last day and half or so on: http://www.bretteveleigh.co.uk/other/Glider_Prototype.rar

It's stand alone because I tried a webgl build and it was pretty janky and normal web player is too much of a pain these days.

 

I was playing Gone Home and really liked just gliding around the environment so I figured that'd be a good exercise to try.

It's a lot rougher than I'd like, the biggest problem is limiting rotation in a way that doesn't feel harsh.

 

I played it, I thought it was pleasant. Thanks for sharing.

Share this post


Link to post
Share on other sites

Thanks clyde, I realised afterwards that there are more suitable threads for sharing games so next time I'll do it there so as to not sidetrack this one. 

Share this post


Link to post
Share on other sites

Hey thumbs,

 

Do you have any experience when it comes to generating content with a seed generator? I'm thinking of creating a map, sim city style.

 

Is there any tutorials that you would recommend, even if they are general? I think I would be able to piece together the tutorial and link it to unity if it wasn't related.

 

Thanks,

 

Joe

Share this post


Link to post
Share on other sites

Basically you just have a set of rules, that execute in the same order every time, these rules make use of the Random class, calling it to get random values. If you pass a seed in to the Random class before your rules start executing, the same seed will cause the rules to produce the same result.  It can get a little weird with Unity because Unity reimplements C#'s Random class, but basically the idea is that you pass in a seed to Random.Seed and every call to Random.value (or Random.range or whatever other methods Random has) will return a value based off that seed. Also, Perlin Noise, very useful for random stuff.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now