- Home /
[resolved]Issues with transform.RotateAround
Hello All!
I'm decent with coding however when it comes to math not so much. I'm working on the spell targeting system for my game and am getting some issues rotating the targeting along a circle if the spell is at maximum range. The targeting reticle is tied to the mouse cursor position. For spells with 0 range (locked to player) everything is fine, for ranged spells everything fine until you reach the maximum range. After you reach maximum range the targeting reticle is still supposed to follow the mouse along the circumference of the circle created by the maximum range. I've got it somewhat working however it moves slowly most of the time (not keeping up with the mouse) and once it gets to about the position in the image below it starts jumping to both sides of the screen rapidly. I've been banging my head against this one for a while but cant seam to get it to work.
Black= Player, player is always facing the cursor in targeting mode.
Blue= maximum range. This is not rendered but value is pulled fine.
Red=is targeting reticle.
Orange= current cursor position
Here is my current code, I cut out the code that's not needed. This is my latest attempt which is pseudo functioning and is getting the issues I noted above.
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class IT_Combat_SpellTargeting : MonoBehaviour
{
private GameObject anchor;
private float range;
private Vector3 rotMask= new Vector3(0,1,0);
string spellType;
List<string> targetTypes= new List<string>();
List<GameObject> targets = new List<GameObject>();
//Initialize our spell targeting obj.
public void initalizeSpellTargeting(GameObject _anchor, bool _showObject,float _scale, float _range, string _spellType, List<string> _targetTypes)
{
transform.parent.localScale = new Vector3(transform.parent.localScale.x*_scale, 1,transform.parent.localScale.z*_scale);
if (!_showObject) renderer.enabled=false;
anchor= _anchor;
spellType= _spellType;
targetTypes= _targetTypes;
range=_range;
}
//restrict our movement to our anchor (caster)
public void Update()
{
Plane reticlePlane = new Plane(Vector3.up, transform.position);
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
float hitdist = 0.0f;
if (anchor !=null)
{
if (reticlePlane.Raycast(ray, out hitdist))
{
Vector3 targetPoint = ray.GetPoint(hitdist);
float currentRange= Vector3.Distance(anchor.transform.position, targetPoint);
if(range==0)transform.parent.rotation=anchor.transform.rotation;
else if(currentRange<=range)transform.parent.position=new Vector3(targetPoint.x,anchor.transform.position.y,targetPoint.z);
else if(currentRange>range && range!=0)transform.parent.RotateAround(anchor.transform.position,rotMask,AngleSigned(transform.position,targetPoint,anchor.transform.position));
}
}
}
public static float AngleSigned(Vector3 v1, Vector3 v2, Vector3 n)
{
Debug.Log (Mathf.Atan2(
Vector3.Dot(n, Vector3.Cross(v1, v2)),
Vector3.Dot(v1, v2)) * Mathf.Rad2Deg);
return Mathf.Atan2(
Vector3.Dot(n, Vector3.Cross(v1, v2)),
Vector3.Dot(v1, v2)) * Mathf.Rad2Deg;
}
}
Any help would be much appreciated since everything I've found and tried has not been able to get me the results I need.
Why not just display the targeting reticle as a GUItexture? I'm not really sure what the problem is? If you want to restrict an objects position to a circle you can normalize it if the magnitude is greater than the max radius and then multiply it by the max radius.
The issue comes in with the highlighted line of code and the function it's calling. Everything follows the cursor smoothly as long as the spell is not at it's maxed range. After it's at it's max range, without the highlighted portion of code, it will just stop moving. With the highlighted line of code it's supposed to follow the cursor, but with it's maximum distance from the anchor point (caster) locked. Think of a ball on a string you can keep pulling it after it's at it's maximum distance but unless your sliding along the circumfrance of the circle created by the maximum length of the string it wont go anywhere
For the most part it's working but it rotates really slow once it's at it's maximum range and is rotating along the circumference of the maximum range and when the targeting reticle reaches about the position in the example picture the spell targeting reticle will jump back and forth 180 degrees along the maximum range.
//restrict our movement to our anchor (caster)
public void Update()
{
Plane reticlePlane = new Plane(Vector3.up, transform.position);
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
float hitdist = 0.0f;
if (anchor !=null)
{
if (reticlePlane.Raycast(ray, out hitdist))
{
Vector3 targetPoint = ray.GetPoint(hitdist);
float currentRange= Vector3.Distance(anchor.transform.position, targetPoint);
if(range==0)transform.parent.rotation=anchor.transform.rotation;
else if(currentRange<=range)transform.parent.position=new Vector3(targetPoint.x,anchor.transform.position.y,targetPoint.z);
//The below is what is causing the issue
else if(currentRange>range && range!=0) transform.parent.RotateAround(anchor.transform.position,rot$$anonymous$$ask,AngleSigned(transform.position,targetPoint,anchor.transform.position));
}
}
}
}
public static float AngleSigned(Vector3 v1, Vector3 v2, Vector3 n)
{
Debug.Log ($$anonymous$$athf.Atan2(
Vector3.Dot(n, Vector3.Cross(v1, v2)),
Vector3.Dot(v1, v2)) * $$anonymous$$athf.Rad2Deg);
return $$anonymous$$athf.Atan2(
Vector3.Dot(n, Vector3.Cross(v1, v2)),
Vector3.Dot(v1, v2)) * $$anonymous$$athf.Rad2Deg;
}
Answer by Raven-Rock · Dec 29, 2013 at 07:49 PM
for all of those who are facing a similar issue I found a simple solution. Since my anchor (spell caster) is always facing the cursor during target mode I cast a ray from the anchor and then used my range modifier in a ray.getPoint call to return the position that my targeting object needed to be at. Not very pretty (does not rotate the gameobject at all) but in my case it dosent need to. Below is final code to get it to do what I wanted.
public void Update()
{
Plane reticlePlane = new Plane(Vector3.up, transform.position);
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
float hitdist = 0.0f;
if (anchor !=null)
{
if (reticlePlane.Raycast(ray, out hitdist))
{
Vector3 targetPoint = ray.GetPoint(hitdist);
float currentRange= Vector3.Distance(anchor.transform.position, targetPoint);
if(range==0)transform.parent.rotation=anchor.transform.rotation;
else if(currentRange<=range)transform.parent.position=new Vector3(targetPoint.x,anchor.transform.position.y,targetPoint.z);
else if(currentRange>range)
{
Ray directionalRay= new Ray(anchor.transform.position,anchor.transform.forward);
transform.parent.transform.position=directionalRay.GetPoint(range);
}
}
}
}
Your answer
Follow this Question
Related Questions
Can you simulate the behavior of Transform.RotateAround using a Rigidbody? 0 Answers
Wheels that just plain won't spin 0 Answers
transform.RotateAround does not rotate to the object I want 2 Answers
Drag to Rotate using Arcball theory ( 3 axis ) 0 Answers
How to limit the rotation of an object 2 Answers