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 /
This post has been wikified, any user with enough reputation can edit it.
avatar image
0
Question by marcosfvc · Oct 14, 2014 at 08:35 PM · movementcircleedgelookattargetrestrict

Restrict player movement to circle's circumference and rotate to lookat

I have a gameObject that I would like to keep restricted to the perimeter of a circle. I want to be able to move the object around the edge of the circle (image example 1) and look in towards the circle (maybe this can be done with SmoothLookAt script) but I do not want the player to be able to enter or leave the circle. Also, I want to prevent the player from looking away from the circle. How can this be done?

alt text I'm using the following script, but the gameobject get away from the circle's edge as the player move (image example 2).

 using UnityEngine;
 using System.Collections;
 
 public class SpiralMovement : MonoBehaviour {
 
     public float walkSpeed;
     Rigidbody playerRigidBody;
     Transform playerTransform;
     public Transform playerPivot;
     Vector3 inputMovement;
 
     // Use this for initialization
     void Awake () {
         playerRigidBody = this.rigidbody; //just caching the rigidbody for speed reasons, rather than calling rigidbody.velocity later, which is much slower.
         playerTransform = this.transform; //same with the transform, caching it for performance reasons
     }
     
     // Update is called once per frame
     void Update () {
 
         playerPivot.position = new Vector3(playerPivot.position.x,playerTransform.position.y,playerPivot.position.z); //make the pivot object the same y height as the player, so it doesn't stay down on the ground
 
         playerPivot.LookAt(playerTransform,Vector3.up); //make the pivot look at the player
 
         Quaternion pivotRotation = playerPivot.localRotation; //get the rotation of the pivot, so that we can adjust the inputs below to be relative to that
 
         inputMovement = Vector3.zero; //resetting the inputMovement vector which will hold all our input information
 
         if(Input.GetKey(KeyCode.W)){
             inputMovement += pivotRotation * Vector3.back;  
         }
         if(Input.GetKey(KeyCode.S)){
             inputMovement += pivotRotation * Vector3.forward;  
         }
         if(Input.GetKey(KeyCode.A)){    
             inputMovement += pivotRotation * Vector3.right;
         }
         if(Input.GetKey(KeyCode.D)){
             inputMovement += pivotRotation * Vector3.left;  
         }
 
         inputMovement = inputMovement.normalized * walkSpeed; //normalising the inputMovement vector so it's not too large and then we can cleanly multiply it by whatever walk speed we desire
 
         playerRigidBody.velocity = new Vector3(inputMovement.x,playerRigidBody.velocity.y,inputMovement.z); //apply the inputMovement vector to the players velocity, but not on the y axis otherwise it will overwrite gravity.
         playerTransform.localRotation = pivotRotation; //keep the player rotated the same as the pivot so it doesn't start walking backwards
 
     }
 }

Edit

This is the working code:

 using UnityEngine;
 using System.Collections;
 
 public class SpiralMovement : MonoBehaviour {
 
     public float walkSpeed;
     Rigidbody playerRigidBody;
     Transform playerTransform;
     public Transform playerPivot;
     Vector3 inputMovement;
     Vector3 circleCenter;
     float radius = 1.787921f;
     public Transform circleCenterObject;
 
     // Use this for initialization
     void Awake () {
         playerRigidBody = this.GetComponent<Rigidbody>(); //just caching the rigidbody for speed reasons, rather than calling rigidbody.velocity later, which is much slower.
         playerTransform = this.transform; //same with the transform, caching it for performance reasons
     }
     
     // Update is called once per frame
     void Update () {
 
         playerPivot.position = new Vector3(playerPivot.position.x,playerTransform.position.y,playerPivot.position.z); //make the pivot object the same y height as the player, so it doesn't stay down on the ground
 
         playerPivot.LookAt(playerTransform,Vector3.up); //make the pivot look at the player
 
         Quaternion pivotRotation = playerPivot.localRotation; //get the rotation of the pivot, so that we can adjust the inputs below to be relative to that
 
         inputMovement = Vector3.zero; //resetting the inputMovement vector which will hold all our input information
 
         /*if(Input.GetKey(KeyCode.W)){
             inputMovement += pivotRotation * Vector3.back;  
         }
         if(Input.GetKey(KeyCode.S)){
             inputMovement += pivotRotation * Vector3.forward;  
         }*/
 
         if(Input.GetKey(KeyCode.A)){
             inputMovement += pivotRotation * Vector3.right;
         }
         if(Input.GetKey(KeyCode.D)){
             inputMovement += pivotRotation * Vector3.left;  
         }
 
         inputMovement = inputMovement.normalized * walkSpeed; //normalising the inputMovement vector so it's not too large and then we can cleanly multiply it by whatever walk speed we desire
 
         
         circleCenter = circleCenterObject.position;
 
         Vector3 offset = transform.position - circleCenter;
         offset = offset.normalized * radius;
         transform.position = offset;
 
         playerRigidBody.velocity = new Vector3(inputMovement.x,playerRigidBody.velocity.y,inputMovement.z); //apply the inputMovement vector to the players velocity, but not on the y axis otherwise it will overwrite gravity.
         playerTransform.localRotation = pivotRotation; //keep the player rotated the same as the pivot so it doesn't start walking backwards
 
     }
 }
 

unity.jpg (26.8 kB)
Comment
Add comment · Show 2
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 MrSoad · Oct 14, 2014 at 11:32 PM 0
Share

You could make a circular corridor from Unity cubes. Then you could turn off(or delete) the $$anonymous$$esh renders so you cannot see the colliders that are restricting the movement of the player... just an idea...

avatar image KpjComp · Oct 14, 2014 at 11:39 PM 2
Share

If I understand correctly you want the player to stick to the perimeter of a circle, then you should just be able to create a DummyObject, place your player a a child of this DummyObject, then offset the PlayerObject inside this DummyObject, then for movement, just rotate the DummyObject,. You wouldn't even need to a have a lookAt script, as it would be looking at the centre anyway.

4 Replies

· Add your reply
  • Sort: 
avatar image
3

Answer by Kiwasi · Oct 15, 2014 at 08:04 AM

To constrain an object to a circle you simply force the object to remain a set distance (the radius) from centre of the circle. Here is a code example.

 Vector3 circleCentre;
 Vector3 radius;
 
 void Update (){
     // Do all other movement first
     // Constrain to a circle with the following
     Vector3 offset = transform.position - circleCenter;
     offset.Normalise();
     offset = offset * radius;
     transform.position = offset;
 }

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

Answer by Namey5 · Oct 15, 2014 at 07:41 AM

The problem may be the fact that you are using a smoothLokAt script. If you use something like transform.LookAt, the object will constantly be snapped looking at the object you set it to. If you use this alone, however, you will have no control over the camera. Then you would simply need to change the movement to left or right instead of pivoting around that point. As far as I can tell, that is what you want.

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

Answer by oakshiro · Nov 21, 2017 at 04:41 PM

float maxRadius = 2.0f var allowedPos = mousePos - initialPos; allowedPos = Vector3.ClampMagnitude(allowedPos, maxRadius); transform.position = initialPos + allowedPos;

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

Answer by iuripujol · Jan 17, 2018 at 07:31 PM

Use Vector3.Cross to get the tangent Vector3 relative to the Radius (circumference radius - transform.position) and the transform.up of the player.

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

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

8 People are following this question.

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

Related Questions

How to limit gameobject movement to circle's circumference? 1 Answer

How to generate the points on a circle edge in a order according to angle. 1 Answer

Gothic-like climbing and edge detection 0 Answers

Moving in circles 1 Answer

Move player in circle around center 0 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