Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 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 KarnEdge · Dec 04, 2013 at 05:05 AM · cameralookatrpgboundaryfixed

Fixed Camera Scene a la FF7 or Resident Evil style

I've been putting together an RPG reminiscent of the Final Fantasy games but I'm having a very difficult time trying to get a fixed camera to work correctly.

The Black Tower game (unfortunately no longer in production) was built in Unity and has the exact kind of Camera setup I want: http://www.youtube.com/watch?feature=player_embedded&v=RByznMHg_L0#t=98

It shows walking around in the town around 1:38 time mark.

I have my fixed camera using LookAt for the player but I can't figure out how to stop it from revealing the end of the map. In that video, the camera follows the player but stops once it reaches the end of the scene and the player continues on.

If anyone can point me in the right direction, it would be much appreciated.

Comment
Add comment
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

2 Replies

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

Answer by Tomer-Barkan · Dec 04, 2013 at 05:53 AM

If you want to keep the Y and Z rotation constant (and zero I guess), so the 'horizion' appears always as a straight line, and it's always facing say north, you're going to have to move the camera around with the player, at least in the X and Z planes, while keeping it's Y coordinates (height) constant, to create a constant 60 degrees diagonal view.

So given the player's position (this example makes the camera look from south to north (from Vector3.back to Vector3.forward), in a 60 degree angle:

 void SetCameraPosition(Transform camera, Transform player, float distanceFromPlayer) {
     Quaternion rotate60Upwards = Quaternion.AngleAxis(60, Vector3.right);
     Vector3 fromPlayerToCamera = (rotate60Upwards * Vector3.back) * distanceFromPlayer;
     camera.position = player.position + fromPlayerToCamera;
 camera.rotation = Quaternion.AngleAxis(60, Vector3.right);        
 }

Now, you can either move the camera the exact same amount that you move the player, whenever the player moves (without rotating the camera any further), or you can simply run the code above every frame (in Update()) so the camera is always updated according to the player location.

Edit: I now understand that you want the camera to stay fixed and rotate, but limit the rotation. What you can do is calculate the most extreme rays of the camera (the corners of the screen), and check that none of them are outside your boundaries. You can do that by placing a huge box collider behind your scene in the area, but only in the area that you want to be visible, so that when there is a point that you don't want to be visible, the collider will not be behind it. Set a specific layer for this collider, say "AreaLayer". Then cast the extreme rays with the AreaLayer as a mask, and see if they hit the collider. If they do not, don't allow the camera to rotate any further:

 void FollowPlayer(Transform player) {
     Quaternion previousRotation = transform.rotation; // remember original rotation
     transform.LookAt(player, Vector3.up); // look at player

     // if looking at player caused the camera to turn outside its bounds, restore previous rotation
     if (IsCameraOutOfBounds()) {
         transform.rotation = previousRotation;
     }
 }

 bool IsCameraOutOfBounds() {
     Ray[] edgeRays = GetCameraEdgeRays(); // get camera extreme rays
     int layerMask = 1 << LayerMask.NameToLayer("AreaLayer"); // raycast layer should only find the "AreaLayer" collider - the collider that depicts the game area
     foreach (Ray ray in edgeRays) {
         // if raycast doesn't hit the area layer collider, camera is out of bounds
         if (!Physics.Raycast(ray, Mathf.Infinity, layerMask) {
             return true;
         }            
     }
     return false;
 }

 // get 4 rays, one for each corner of the camera's view
 Ray[] GetCameraEdgeRays() {
     Ray[] rays = Ray[4];
     ray[0] = camera.ScreenPointToRay(0, 0); 
     ray[1] = camera.ScreenPointToRay(0, Screen.height);
     ray[2] = camera.ScreenPointToRay(Screen.Width, 0);
     ray[3] = camera.ScreenPointToRay(Screen.Width, Screen.height);

     return rays;
 }
Comment
Add comment · Show 4 · 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 KarnEdge · Dec 05, 2013 at 12:51 AM 0
Share

I appreciate the input but I'm really hoping to use a camera that doesn't change its transform to follow the player ins$$anonymous$$d uses LookAt to follow. I'm having a problem with keeping the camera from seeing the end of the map.

In the video, the camera stays in one position and uses LookAt to follow the player. As the player reaches an edge of the map, the camera reaches a boundary and stops following the player. That's what I'm trying to do.

avatar image Tomer-Barkan · Dec 05, 2013 at 06:37 AM 0
Share

Sorry about that. Edited my answer now.

avatar image Womrwood · Dec 05, 2013 at 01:35 PM 0
Share

It is a much simpler solution I appreciated it.

avatar image KarnEdge · Dec 11, 2013 at 04:31 AM 0
Share

Sorry, it's been several days of overtime and bits of free time to mess with this so answer accepted.

Unfortunately, as well as this code performs it's setup in a way that if you take the camera out of AreaLayer, it will lock the camera. Then, if you move around to another position where you are back in the AreaLayer, the camera will jump to that position. It doesn't seem possible to do a fixed camera without hardcoding clamping boundaries so it slides along the sides of the area.

I've tried so many different ways but to no avail. Just seems I'll have to just put in the boundary floats for top, bottom, left and right on each scene. I was hoping to make my camera script automatically figure out the boundaries and move the camera accordingly no matter what Area I have in the scene.

Thank you @tbkn, definitely a learning experience!

avatar image
0

Answer by Womrwood · Dec 05, 2013 at 01:59 AM

You could establish a limit angle of rotation on the Y and X axis.

Store the the orientation of the camera at the center of the scene in a variable called middleOrientation. Every frame get a new orientation looking directly to the target player called targetOrientation. Now test the angle between the X axis of the middleOrientation with the X axis of the targetOrientation and check if it exceeds the limit angle rotation about that angle if not continue otherwise you will have to undo the orientation with exceedAngle - limitAngle. Do the same thing with the Y axis.

To get the angle between 2 axis you can use the following code:

 var vec1=Vector3(2,3,4); 
 var vec2= Vector3(1,-2,3);
 //Get the dot product
 var dot:float = Vector3.Dot(vec1,vec2);
 // Divide the dot by the product of the magnitudes of the vectors
 dot = dot/(vec1.magnitude*vec2.magnitude);
 //Get the arc cosin of the angle, you now have your angle in radians 
 var acos = Mathf.Acos(dot);
 //Multiply by 180/Mathf.PI to convert to degrees
 var angle = acos*180/Mathf.PI;
 //Congrats, you made it really hard on yourself.
 print(angle);
Comment
Add comment · Show 4 · 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 Womrwood · Dec 05, 2013 at 02:30 AM 0
Share

I messed up the angles when rotation on the Y axis you can test the 2 forward vectors and when rotation on the X axis you can test the 2 up vectors.

avatar image Tomer-Barkan · Dec 05, 2013 at 06:20 AM 1
Share

@Womrwood you can get angle between two vectors using Vector3.Angle:

 var angle = Vector3.Angle(vec1, vec2);


avatar image Womrwood · Dec 05, 2013 at 10:10 AM 0
Share

Thanks, I am new to Unity^^ but a little math knowledge is good too.

avatar image Tomer-Barkan · Dec 05, 2013 at 11:34 AM 0
Share

lol, not just good, but essential... Especially geometry.

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

18 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Attaching camera to instantiated object 1 Answer

Changing The Camera Position & Offsetting LookAt 2 Answers

CameraZoom Changeing Position 0 Answers

Lock look rotation first person. 0 Answers

Camera rotate to look at GameObject from Raycast 3 Answers


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