Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by Evolht · Oct 17, 2016 at 05:00 AM · translatecamera movementisometriclocal space

Translate using local space to center Camera on gameObject

Hi All,

I have a camera that is rotated 45 degrees on both the x and y axis, as we are working on an isometric game. That camera is looking at some cubes.

I want to make my camera smooth pan using lerp to whatever direction is required in order to center on a gameObject that is being passed in.

When panning right now, I translate using space.self in order to preserve our isometric rotation. I don't want rotate the camera, as that would break our isometric view, so using the lookat function is out.

I already use panning with right click and dragging that uses space.self, but I haven't been able to apply that to this idea.

I've looked at the question below and believe I must need to create a plane that is also working on the same angle as my camera. http://answers.unity3d.com/questions/400209/moving-camera-to-center-on-clicked-object.html

Here is my current script. It wont be too cohesive at the moment as I've merged a bunch of different scripts to get the functionality I want.

Can someone please point me in the right direction? :)

 using UnityEngine;
 
 
 public class DynoCam : MonoBehaviour
 {
     public static DynoCam instance;
 
     public float PanSpeed = 1;
     public int speed = 3;
     private Vector3 dragOrigin;
 
     Vector3 startPos;
 
     public bool cameraDragging = true;
     public bool CanDoCameraStuff = true;
 
     float outerLeft = -20f;
     float outerRight = 2f;
     float outerUp = 45f;
     float outerDown = 15f;
 
 
     float zoomSensitivity = 15.0f;
     float zoomSpeed = 2.0f;
     float zoomMin = 3.0f;
     float zoomMax = 30.0f;
 
     private float zoom;
 
     public Camera selectedCamera;
     public float MINSCALE = 2.0F;
     public float MAXSCALE = 5.0F;
     public float varianceInDistances = 5.0F;
     private float touchDelta = 0.0F;
     private Vector2 prevDist = new Vector2(0, 0);
     private Vector2 curDist = new Vector2(0, 0);
     private float startAngleBetweenTouches = 0.0F;
     private int vertOrHorzOrientation = 0;
     private Vector2 midPoint = new Vector2(0, 0);
 
    
 
 
     void Start()
     {
         if (instance == null)
             instance = this;
         else
             Destroy(this);
 
         startPos = transform.position;
         selectedCamera = Camera.main;
         zoom = Camera.main.orthographicSize;
         if (Application.platform != RuntimePlatform.Android && Application.platform != RuntimePlatform.IPhonePlayer)
         {
             zoom = Camera.main.orthographicSize * 1.5f;
         }
     }
 
     public void ResetCameraPosition()
     {
         transform.position = startPos;// GetCenteredCameraPos();
         Camera.main.orthographicSize = 3;
         Camera cam;
         Plane[] planes;
         cam = Camera.main;
 
         int loopProtection;
         foreach (GameObject G in generateLevel.instance.LandMass)
         {
             loopProtection = 0;
             while (true)
             {
 
                 planes = GeometryUtility.CalculateFrustumPlanes(cam);
                 //if (!GeometryUtility.TestPlanesAABB(planes, anObjCollider.bounds))
                 if (!GeometryUtility.TestPlanesAABB(planes, G.GetComponent<GridTile>().HeldBlock.GetComponent<Collider>().bounds))
                 {
                     cam.orthographicSize += 0.5f;
 
                 }
                 else
                 {
                     break;
                 }
                 loopProtection++;
                 if (loopProtection > 15)
                     break;
             }
 
         }
 
         cam.orthographicSize += 3.5f;
         cam.orthographicSize = Mathf.Clamp(cam.orthographicSize, 5, 40);
     }
 
     private Vector3 GetCenteredCameraPos()
     {
 
         float x = 0f;
         float y = 0f;
         float z = 0f;
         foreach (GameObject pos in generateLevel.instance.LandMass)
         {
             x += pos.transform.position.x;
             y += pos.transform.position.y;
             z += pos.transform.position.z;
         }
         return new Vector3(x / generateLevel.instance.LandMass.Count, y / generateLevel.instance.LandMass.Count, z / generateLevel.instance.LandMass.Count);
     }
     
 
     void Update()
     {
 
         if (CanDoCameraStuff)
             if (GameManager.instance.CurrentState == GameState.Play)
             {
                 //
                 //  if pc version
                 //
                 if (Application.platform != RuntimePlatform.Android && Application.platform != RuntimePlatform.IPhonePlayer)
                 {
                     zoom -= Input.GetAxis("Mouse ScrollWheel") * zoomSensitivity;
                     zoom = Mathf.Clamp(zoom, zoomMin, zoomMax);
                 }
 
                 //
                 //  if mobile version
                 //
                 else
                 {
 
                     if (!GodController.instance.ClickedOnTile)
                     {
                         //if (Input.touchCount != 0)
                         //   
                         if (Input.touchCount == 1 && Input.GetTouch(0).phase == TouchPhase.Moved)
                         {
                             //Debug.Log(Input.touchCount);
                             Vector2 touchDeltaPosition = Input.GetTouch(0).deltaPosition;
                             float panSpeedMobile = 1f * Time.deltaTime;
                             Vector3 lerpToPos = new Vector3(-touchDeltaPosition.x * panSpeedMobile, -touchDeltaPosition.y * panSpeedMobile, 0);
 
                             transform.Translate(-touchDeltaPosition.x * panSpeedMobile, -touchDeltaPosition.y * panSpeedMobile, 0);
                             //transform.position = Vector3.Lerp(transform.position, transform.position + lerpToPos, Time.deltaTime * panSpeedMobile);
 
                         }
                         else if (Input.touchCount == 2 && Input.GetTouch(0).phase == TouchPhase.Moved && Input.GetTouch(1).phase == TouchPhase.Moved)
                         {
 
 
                             midPoint = new Vector2(((Input.GetTouch(0).position.x + Input.GetTouch(1).position.x) / 2), ((Input.GetTouch(0).position.y - Input.GetTouch(1).position.y) / 2)); //store midpoint from first touches
                             curDist = Input.GetTouch(0).position - Input.GetTouch(1).position; //current distance between finger touches
                             prevDist = ((Input.GetTouch(0).position - Input.GetTouch(0).deltaPosition) - (Input.GetTouch(1).position - Input.GetTouch(1).deltaPosition)); //difference in previous locations using delta positions
                             touchDelta = curDist.magnitude - prevDist.magnitude;
 
                             if ((Input.GetTouch(0).position.x - Input.GetTouch(1).position.x) > (Input.GetTouch(0).position.y - Input.GetTouch(1).position.y))
                             {
                                 vertOrHorzOrientation = -1;
                             }
                             if ((Input.GetTouch(0).position.x - Input.GetTouch(1).position.x) < (Input.GetTouch(0).position.y - Input.GetTouch(1).position.y))
                             {
                                 vertOrHorzOrientation = 1;
                             }
 
                             if ((touchDelta < 0)) //
                             {
                                 zoom = Mathf.Clamp(Camera.main.orthographicSize + (1 * speed), zoomMin, zoomMax);
                             }
 
 
                             if ((touchDelta > 0))
 
                             {
                                 zoom = Mathf.Clamp(Camera.main.orthographicSize - (1 * speed), zoomMin, zoomMax);
                             }
 
                         }
                         Camera.main.orthographicSize = Mathf.Clamp(Camera.main.orthographicSize, zoomMin, zoomMax);
 
                     }
                 }
             }
     }
 
     void LateUpdate()
     {
 
         if (GameManager.instance.CurrentState == GameState.Play)
         {
 
             Camera.main.orthographicSize = Mathf.Lerp(Camera.main.orthographicSize, zoom, Time.deltaTime * zoomSpeed);
 
 
             //
             //  if pc version
             //
             if (Application.platform != RuntimePlatform.Android && Application.platform != RuntimePlatform.IPhonePlayer)
             {
                 Vector2 mousePosition = new Vector2(Input.mousePosition.x, Input.mousePosition.y);
 
                 float left = Screen.width * 0.2f;
                 float right = Screen.width - (Screen.width * 0.2f);
 
                 if (mousePosition.x < left)
                 {
                     cameraDragging = true;
                 }
                 else if (mousePosition.x > right)
                 {
                     cameraDragging = true;
                 }
 
                 if (cameraDragging)
                 {
                     if (Input.GetMouseButtonDown(1))
                     {
                         dragOrigin = Input.mousePosition;
                         return;
                     }
 
                     if (!Input.GetMouseButton(1)) return;
 
                     Vector3 pos = Camera.main.ScreenToViewportPoint(Input.mousePosition - dragOrigin);
                     Vector3 moveX = new Vector3(pos.x * PanSpeed, 0, 0);
                     Vector3 moveY = new Vector3(0, pos.y * PanSpeed, 0);
 
                     if (moveX.x > 0f)
                     {
                         if (this.transform.position.x < outerRight)
                         {
                             transform.Translate(moveX, Space.Self);
                             
                         }
                     }
                     else
                     {
                         if (this.transform.position.x > outerLeft)
                         {
                             transform.Translate(moveX, Space.Self);
                         }
                     }
                     if (moveY.y > 0f)
                     {
                         if (this.transform.position.y < outerUp)
                         {
                             transform.Translate(moveY, Space.Self);
                         }
                     }
                     else
                     {
                         if (this.transform.position.y > outerDown)
                         {
                             transform.Translate(moveY, Space.Self);
                         }
                     }
                 }
 
             }
 
             //
             //  if mobile version
             //
             else
             {
 
             }
         }
     }
 }
 
 



Comment
Add comment · Show 1
10 |3000 characters needed characters left characters exceeded
â–¼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Evolht · Oct 17, 2016 at 09:55 PM 0
Share

Here's a supplementary image. I want to be able to click on any single one of those blocks, and the camera would move over to the right and the block should be in the center of the screen

Supplementary image

isometric.png (93.6 kB)

2 Replies

· Add your reply
  • Sort: 
avatar image
1
Best Answer

Answer by YesNoKonrad · Oct 18, 2016 at 01:55 AM

on click, you could send a Raycast from your camera through the middle of the screen onto the object plane ( i assume that every tile of your game exists at the same height? like y = 0 for example? so you would create an invisible plane with a collider and chose raycast as gameobject.layer (has to be created), your raycast uses then the raycast-layermask)

this gives you the position you are currently looking on, now you get the position from the object you clicked on and substract your viewposition from it.

the result is a translation-vector that should do the trick. simply add the vector to your camera position.

Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
â–¼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Evolht · Oct 18, 2016 at 06:31 AM 0
Share

Hi @YesNo$$anonymous$$onrad! Thank you for getting back to me.

This is where I managed to get to. Every tile of my game exists on Y level 20. I am guessing at a lot of things with the code below.

                         Plane plane = new Plane(new Vector3(0, 20, 0), Vector3.zero);
                         Vector3 v3Center = new Vector3(0.5f, 0.5f, 0.0f);
                         Ray ray = Camera.main.ViewportPointToRay(v3Center);
                         float fDist;
                         if (plane.Raycast(ray, out fDist))
                         {
                             Vector3 v3Hit = ray.GetPoint(fDist);
                             Vector3 v3Delta = SelectedTile.transform.position - v3Hit;
                             Camera.main.transform.Translate(v3Delta);
                         }

I wasn't really sure about working with the raycast layer when working with the code above, as from my understanding, plane.raycast only interacts with both the plane and the ray that I've made from the camera?

Regardless, I'm still sure that I need a plane that is made from my camera viewport somehow, but I don't know if that is true. Currently, with the above, clicking on a block will send the camera very far up and to the left, even if I had the camera centered on the tile.

avatar image YesNoKonrad Evolht · Oct 18, 2016 at 02:53 PM 1
Share

You misunderstood the constructor of the plane.

The first vector describes the normal of the plane and the second the distance from center as a point. If you are familiar with math then you can recognize that that is one of three methods to define a plane: You define a point in space that lies on your plane, and the inclination of the plane via the normal

So your plane is placed at 0,0 and if the costructor does not normalize the vector that should be normal (length 1) then it is also strechted by 20.

it should look like this

 Plane plane = new Plane(new Vector3(0, 1, 0), new Vector3(0, 20, 0));

Edit 2: You can ignore the stuff with the raycast-mask, that was for a finite plane, id est a simple object with a mesh. the solution you found is way more elegant.

Edit: Tipp: Whenever you use a class that you never used before, look into it in the scripting section of the documentation. It's invalueable. :)

avatar image
1

Answer by Zodiarc · Oct 18, 2016 at 07:03 AM

You can make the camera a child of an empty game object (let's call it beam). This beam should always stay at ground level. Then you can lerp the position of the beam to your wanted position and the camera will follow while keeping its rotation (but make sure the camera is actually looking at the beam). I'm using the same technique here: https://www.youtube.com/watch?v=b6H_9M8Va6w

Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
â–¼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image YesNoKonrad · Oct 18, 2016 at 03:19 PM 0
Share

+1 For avoiding raycasts, which are expensive. Simple but effective. I really like it.

avatar image Zodiarc YesNoKonrad · Oct 19, 2016 at 07:57 AM 0
Share

@YesNo$$anonymous$$onrad actually it uses one raycast so that the empty parent always stays on top of the terrain and other props like buildings. Baiscally it's a simple drag & drop rts/tbs camera solution which works out of the box. But in this case the raycast isn't really needed.

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

4 People are following this question.

avatar image avatar image avatar image avatar image

Related Questions

Move camera along 2 axes in WorldSpace 2 Answers

Center Object in Viewport 1 Answer

Isometric game, Camera movement breaks when fps drops. 1 Answer

Moving a Rotated Camera 0 Answers

Why are my controls laggy 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges