• Advertisement
Sign in to follow this  

Unity Third person camera with free look

This topic is 740 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I have been trying to implement a third person camera syste: m in Unity, but not based on the default system. My goal is something more like Unreal Engine system, used also in Mass Effect or The Witcher 2/3. This system provides a camera free look, and then the character moves towards the camera direction.

My current approach consists of having a pivot GameObject, that follows the playecr GameObject. The pivot handles camera free look and other things like selecting objects in front of the camera (which right no, is not working well), and the crosshair (totally missing):

public class PivotControl : MonoBehaviour {
	float rotationY = 0F;
	Camera cam;
	Text label;

	// Use this for initialization
	void Start () {
		cam = gameObject.GetComponentInChildren<Camera> ();
		label = GameObject.Find ("Label").GetComponent<Text>();;
	}
	
	// Update is called once per frame
	void Update () {		
		if (Input.GetAxis ("Mouse X") != 0 || Input.GetAxis ("Mouse Y") != 0) {
			
			float rotationX = gameObject.transform.localEulerAngles.y + Input.GetAxis("Mouse X") * 2f;

			rotationY += Input.GetAxis("Mouse Y") * 5f;		
			gameObject.transform.localEulerAngles = new Vector3(-rotationY, rotationX, 0);
			cam.transform.LookAt(cam.ViewportToWorldPoint(new Vector3(0.5f, 0.5f, cam.farClipPlane)));
			RaycastHit hit;					
			Ray ray =  cam.ViewportPointToRay(new Vector3(0.5F, 0.5F, 0));
			if (Physics.Raycast (ray, out hit, 100)) {
					 
				if (hit.collider.tag=="Interactable")
					label.text = "Press E to interact with "+hit.collider.name;
			} else {
				label.text = "";
			}
		}
	}
}

The player script handles character movement and I have noticed that the rotatio towards camera direction works fine for small angles, when the difference between the player direction and the camera direction is not too large:

public class PlayerControl : MonoBehaviour {

	public GameObject pivot;
	Animator anim;
	int direction = 0;
	int FORWARD  = 1;
	int BACKWARD = 2;
	int LEFT = 3;
	int RIGHT = 4;

	// Use this for initialization
	void Start () {
		//cam = gameObject.GetComponent<Camera> ();
		//Cursor.visible = false;
		//Cursor.lockState = CursorLockMode.Locked;
		anim = gameObject.GetComponent<Animator> ();
	}
	
	// Update is called once per frame
	void Update () {
		Vector3 rot;

		if (Input.GetKeyDown (KeyCode.W)) {
			direction = FORWARD;
		} else if (Input.GetKeyDown (KeyCode.S)) {
			//go back
			direction = BACKWARD;
		} else if (Input.GetKeyDown (KeyCode.A)) {
			direction = LEFT;
		} else if (Input.GetKeyDown (KeyCode.D)) {
			direction = RIGHT;
		} else if (Input.GetKeyUp (KeyCode.W) || Input.GetKeyUp (KeyCode.S) || Input.GetKeyUp (KeyCode.A) || Input.GetKeyUp (KeyCode.D)) {
			direction = 0;
		}

		switch (direction) {
			case 0: //do nothing
				anim.SetInteger("State",0);
				break;
			case 1:		//forward
				rot = gameObject.transform.localEulerAngles;
				rot.y = pivot.transform.localEulerAngles.y;
				gameObject.transform.rotation = Quaternion.Slerp (gameObject.transform.rotation, Quaternion.Euler (rot), 5f * Time.deltaTime);
				anim.SetInteger("State",1);
				gameObject.transform.Translate (0, 0, 20 * Time.deltaTime);				
			pivot.transform.position = Vector3.Slerp(pivot.transform.position, gameObject.transform.position, 5f *Time.deltaTime);
				break;
			case 2: //
				rot = gameObject.transform.localEulerAngles;
				rot.y = pivot.transform.localEulerAngles.y+180f;
				gameObject.transform.rotation = Quaternion.Slerp (gameObject.transform.rotation, Quaternion.Euler (rot), 5f * Time.deltaTime);
				anim.SetInteger("State",1);
				gameObject.transform.Translate (0, 0, 20 * Time.deltaTime);
				pivot.transform.position = Vector3.Slerp(pivot.transform.position, gameObject.transform.position, 5f *Time.deltaTime);
				break;
			case 3:
				rot = gameObject.transform.localEulerAngles;
				rot.y = pivot.transform.localEulerAngles.y-90f;
				gameObject.transform.rotation = Quaternion.Slerp (gameObject.transform.rotation, Quaternion.Euler (rot), 5f * Time.deltaTime);
				anim.SetInteger("State",1);
				gameObject.transform.Translate (0, 0, 20 * Time.deltaTime);
				pivot.transform.position = Vector3.Slerp(pivot.transform.position, gameObject.transform.position, 5f *Time.deltaTime);
			break;
			case 4:
				rot = gameObject.transform.localEulerAngles;
				rot.y = pivot.transform.localEulerAngles.y+90f;
				gameObject.transform.rotation = Quaternion.Slerp (gameObject.transform.rotation, Quaternion.Euler (rot), 5f * Time.deltaTime);
				anim.SetInteger("State",1);
				gameObject.transform.Translate (0, 0, 20 * Time.deltaTime);				
				pivot.transform.position = Vector3.Slerp(pivot.transform.position, gameObject.transform.position, 5f *Time.deltaTime);
			break;
		}
	}
}

Can somebody, please, suggest some improvements for this code? Im specially interested in solving the selection problem and implementing the crosshair.

 

Share this post


Link to post
Share on other sites
Advertisement

I would break out the label and code for interactive object checking into a different component, they aren't really related to a third person camera look.  You could easily do the raycasting from the camera in another component attached to the same object.  It'll keep things cleaner, and more re-usable.

 

Your movement code is odd.  I would avoid looking at keys, and look at input controls.  That would make it trivial to swap to using WASD or a twin stick controller.   I'd also set the a vertical & horizontal movement axis separately, your else ifs block holding both W and A, for example.  Granted it's been ages since I've played a Mass Effect, so maybe that's by design.  Rather than switching off direction and rotating, you could project the camera's forward and right(or left) vectors onto a 2d plane, and then scale those by the vertical and horizontal movement axis to move camera relative.

 

Some Nits:

Be consistent, if you are setting Direction as LEFT, RIGHT, etc, use LEFT, RIGHT in your switch-case, not 0, 1, 2, 3.  If you're not checking for null or asserting, you should probably stick a [requirecomponent] trait on your classes for the things you require to exist.  Try not to stick magic numbers in your code, add some [serializefield] floats for those vertical and horiztonal look axis scalars.

 

EDIT:  For selection, I think I would do it in two stages, I would get all the interactive objects that are within X distance to the player, get rid of any the camera is not facing (dot check), and if it's only one, then I would show that one.  If there is more than one, I would create a line from the camera, do a distance-line check, and take the closest one.  That makes it less fiddly for the player, if they're standing in the elevator, they probably want to activate it.  If they are near multiple corpses, or are standing in the elevator but there is a dead corpse to loot, if they're looking close to the corpse, they probably want to loot it.  (You'll notice that exact same logic would work for a first person game too -- and strengthens my argument for ripping it out into it's own component)

Edited by ferrous

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
  • Advertisement
  • Popular Tags

  • Advertisement
  • Popular Now

  • Similar Content

    • By NfiniT
      Hello!  Our team is a searching for a 2D Artist looking to add a title (whether the first one, or one of many) to his portfolio, with the opportunity to pursue a long-term partnership.
       
      Position & Responsibilities:
      Our team is looking for a 2D Artist to help produce finalized art assets from our current concepts and help finish our current working prototype.  This includes various stylized cartoon characters, level components/objects, background art, and possible UI elements.  The entire team can either provide you the concept art, or let you have extended creative freedom, it's up to you--whichever you feel is better suited for your process.
      Also, although this is not a requirement, if you want to expand your skill-base, you can dabble in the other aspects as well, be it animation, programming, design, narrative, etc.
      Project Description:
      Our project is titled Stanley and the Clocktower Caper, and is a casual 2D platformer with a puzzle element and child-friendly combat.  Our goal is a funny, relaxing experience that intentionally does not take itself seriously.
      Set in the steam-punk styled town, our protagonist Stanley (a sloth), is a local tinkerer and keeper of the town's clocktower.  The town and clocktower have been invaded (story-related reasoning) and are swarming with spiders who've gummed up the cogs with webs, removed gears and all-around caused chaos.  Stanley must make his way down, out of the clocktower, which will require unclogging gears, finding missing pieces to levers, switches, gear-trains, etc.  While all of this is a tall order, thankfully Stanley is an avid consumer of Slothbux, a particularly caffeinated brand of coffee which gives Stanley quite the pick-me-up (how else do you think a sloth manages to be a tinkerer and get so many odd things done!? ) and allows him to accomplish some feats of speed, agility and strength not normally attainable otherwise!
      This game will consist of Stanley escaping the tower, which is apparently going to be a pretty big tower for such a little sloth!  It must have a lot of clocks...  Pending good reception on release (this is discussed below), we would happily consider a follow-up adventure.
      Release & Other Business Stuff:
      We'll be releasing on PC, and are targeting a July release--it is an admittedly small window, but a lot of the functionality already exists and we've got a realistic perception of what we're capable of as a small team and have kept the scope of our project focused accordingly.  Distribution channel is not finalized, though the most obvious and likely candidates are Steam and Itch.io.  Price-point of the final product is TBD.
      You will be included in the rev-share, and of course that's regardless of whether you fill the role and leave or decide to stay with us for future titles.
      Team:
      There are currently four of us, you will be the fifth.
      1) (Me) Our resident programmer, and dabble in both concept art & Design. 
      2) Our producer (handles scheduling, keeping things organized and on task), who also handles animation & dabbles in design.
      3) Our lead designer (story, level layout, etc.), who also does a bit of concept art
      4) Our sound engineer, who is also using the opportunity to learn a bit of programming.
      Links to Stuff:
      Working prototype--https://iconoclast209.itch.io/stanley
       
      If you would like to fill the role or have more questions, feel free to reach out to me on PM or on Discord at Bryant - NfiniT#5890 
      Thank you for your time!
    • By revolverolver
      Aloha,
      First time working in 3D. Not as difficult as I thought it would be although I am pretty much a complete beginner in Blender. I chose the low poly style because I like how it looks and it is a lot easier than trying to make it look realistic.
      The gameplay is pretty much all physics driven which makes it feel satisfying to play. If it looks any fun then please check it out. I could really use a review or two.
      Here are some promo codes so that you don't have to pay a dime to download it: 
      PJW7MTMWL3W3
      A4JLYRPTXMJH
      AXRKPMAT7AAY
      YMFJPTPJ9EX3
      JY3W6FNKTM6L
       
      App store link: https://itunes.apple.com/us/app/flip-trickster/id1351027839?l=en&mt=8
       
       
    • By Innoc uous
      I'm working on a space game, and I suck at art. I would love to get some help from someone who is more skilled than me. Things I need include modular space ship parts and GUI elements. Nothing too fancy, just functional so I can get a prototype put together. This could potentially become a serious project, but for now this is just a hobby project.
       
      In this video, you can see a few things I already completed
      :2018-02-24 20-08-13.flv2018-02-24 20-08-13.flv
    • By Innoc uous
      If you want to incorporate noise into your shaders, the Turbulance Library has you covered. Using code I gathered from this library, I made a cginc file that contains all you need to easily implement noise into your unity shaders. Who knows how this stuff works, but man, does it work well!
       
      https://pastebin.com/LLCUpJut
       
      Here is an example of what you can create using these noise functions.
       
    • By Nio Martinez
      I'll be buying a new laptop as my workstation for building games, Mostly 3D but not hard core. 
       
      I'm stuck at choosing between these 2 specs below. Does this really matter and if so, can some one tell my how and why it matters. 
      Choice1:
      Intel core i5-8250U (8th gen Kabylake refresh)(6 MB Smart Cache, 1.6 GHz Base with Turbo Boost up to 3.4 GHz) 4 cores 8 threads
      RAM 8 GB DDR4 (2400 MHz)
      GPU 2 GB DDR5 Nvidia MX150 256 bit
      SSD: yes
      Choice2:
      Intel core i7-7500U 2.70GHz Base Processor (4M Cache, up to 3.50 GHz Boost) 2 Cores, 4 Threads
      RAM 4 GB DDR4 (1800 MHz)
      GPU 2 GB DDR5 Nvidia GeForce 940MX 256 bit
      SSD: No
       
  • Advertisement