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
1
Question by MasterLetch · Apr 02, 2012 at 09:17 AM · rotatecoordinatesparenting

local space and rotation issues

So i have a "ship", with "turrets" that are parented... I have a script that identifies close targets and sets them, the turrets then use these targets to coordinates to fire... problem comes in when they do not rotate correctly.

I could only guess that its... a) because i have no idea what axis "LookAt" actually is aligning to b) because I most likely have "local space - world space" issues

 public virtual void Fire(){    
     Ray raycheck = new Ray(transform.position, target.transform.position);
     
     if (!ship.GetComponent<Renderer>().bounds.IntersectRay(raycheck)){
     transform.rotation = Quaternion.Slerp (transform.rotation, Quaternion.LookRotation(target.transform.position,Vector3.right), 0.7f * Time.deltaTime);
         
     if (!IsInvoking("AttackHandler"))
         Invoke("AttackHandler", 5);
     }
 }
 
 public virtual void AttackHandler(){
     
     Rigidbody Shot;
     Shot = Instantiate (Ammo,mount.transform.position,Quaternion.LookRotation(target.transform.position)) as Rigidbody;
     Shot.velocity = Shot.transform.TransformDirection(Vector3.forward)*200 * Time.deltaTime;
 }

Quite the amount to look throught I know. on a slightly different note. what is the best way to rotate towards a target with a certain speed?

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

1 Reply

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

Answer by aldonaletto · Apr 02, 2012 at 12:31 PM

The main problem here is that you're confusing points and vectors. Although both are stored in Vector3 structures, the meanings are different. A point is a location in the 3D space, while a vector represents a direction - think of it as an "arrow" from (0,0,0) to the vector coordinates: Vector3.up, for instance, is (0,1,0), what means a vertical arrow (from y=0 to y=1).
But there are other problems too: you're using Quaternion.Slerp to turn gradually to the target, but this will only work if you call the Fire function each Update (or in a coroutine) - Quaternion.Slerp rotates a little each time it's called, thus using it only once gives no noticeable effect. Another weird thing: why are you checking intersection between the ray and renderer.bounds? To avoid shooting "across" your own ship? bounds is an AABB, Axis Aligned Bounding Box, and grows or shrinks when you rotate your ship.
But lets get back to the basics: you should calculate a dir vector in the direction ship->target, what you can do just subtracting ship.position from target.position. When shooting, start a coroutine that will turn gradually to the target during duration seconds and then shoot. To avoid multiple coroutines running in the same turret, a shooting flag is used:

public virtual void Fire(){ Vector3 dir = target.transform.position-transform.position; Ray raycheck = new Ray(transform.position, dir); if (!ship.GetComponent< Renderer>().bounds.IntersectRay(raycheck)){ // call Shoot only when previous shot has finished if (!shooting) StartCoroutine(Shoot(target.transform)); } }

public float duration = 0.5f; // time in seconds to turn to target bool shooting = false; // flag to avoid multiple Shoot calls

IEnumerator Shoot(Transform tgt){ shooting = true; // Shoot is running! Quaternion rot0 = transform.rotation; // save initial rotation float t = 0.0f; while (t < 1.0f){ // turn to the target during duration seconds t += Time.deltaTime/duration; // advance variable t Vector3 dir = tgt.position-transform.position; // update the direction each loop // sets rotation to an intermediate direction proportional to t: transform.rotation = Quaternion.Slerp (rot0, Quaternion.LookRotation(dir), t); yield return 0; // let Unity breath till the next frame } Rigidbody Shot; Shot = Instantiate(Ammo, mount.transform.position, transform.rotation) as Rigidbody; Shot.velocity = dir * 20; // shoot in the target direction shooting = false; // Shoot has finished } NOTE: This is untested C# code, thus may contain some errors.

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 MasterLetch · Apr 02, 2012 at 02:41 PM 0
Share

I probably shouldn't have sent so much mucked up code, as i was using a slightly different set of functions before screwing with it to get it working... tho i never once thought to calculate my own vector using 2 positions, that was very helpful.

I was using Quaternion.RotateTowards so that i could get a constant speed and variable time, I just had my speed set so low it never really pointed at its target...

tho i don't totally understand why the coroutine is nessesary as you can block a regular function the same way

avatar image aldonaletto · Apr 02, 2012 at 03:44 PM 0
Share

A coroutine works this way: StartCoroutine creates an internal object with the coroutine code attached, and starts executing this code. When a yield instruction is found in the code, Unity stops executing it and returns to the caller routine. In the next frame, after executing all Updates, Unity resumes automatically the coroutine right after the yield, and does it over and over until the coroutine finishes, when the internal object is destroyed.
In other words, coroutines are the ideal way to execute loops without freezing Unity, because one iteration is executed per frame. In this case, Fire starts the coroutine Shoot and returns - Unity does the job automatically for you.

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

Camera follow rotating object 1 Answer

How to flip objects that are currently rotating? 1 Answer

Rotate objects towards gps coordinates 0 Answers

Parenting without transform.rotation 1 Answer

Is it possible to rotate uv coordinates in a script? 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