Restore sphere to orientation? - unity3d

Though I begin with a very nicely, oriented globe:
After a lot of manual intervention and spinning, the globe may look like this:
Obviously, I should be implementing some sort of restoration function that will restore the globe on a certain axis to a point.
I have naively created the following code:
if(transform.parent.rotation.eulerAngles.y != 0)
{
goalRotation.eulerAngles = new Vector3(transform.parent.rotation.eulerAngles.x, transform.parent.rotation.eulerAngles.y, 0);
transform.parent.rotation = Quaternion.Slerp(transform.parent.rotation, goalRotation, Time.deltaTime);
}
However, this obviously does not work. It is definitely rotating the globe, but it's not moving as expected...
Is there anyone with more experience with Slerp or something similar that can rotate my globe to a 0 point?
As always, any help or advice is much appreciated.
EDIT: In case I wasn't clear before, I am looking to achieve something like this: https://gfycat.com/PeacefulJubilantCottontail (This is my solution to the problem). I did try to use other solutions here, but I guess there was a misunderstanding because they did not work.
While, the following naive code sorta works, I still feel there is a better way to do it...
if (fix && (lastControlled + 5f < Time.time))
{
goalRotation.eulerAngles = new Vector3(90, transform.parent.rotation.eulerAngles.y, 0);
transform.parent.rotation = Quaternion.Slerp(transform.parent.rotation, goalRotation, Time.deltaTime);
}
if (fix && (transform.parent.rotation.eulerAngles.x == 90) && (transform.parent.rotation.eulerAngles.z == 0))
{
fix = false;
}
The only real remaining issue I am having is that Slerp works towards the desired point, but it does not take the quickest path. Any further help would be appreciated.

Is this what you are trying to do?
quaternion defaultRotation = transform.parent.rotation;
bool returnToDefault = false;
void Update()
{
if(returnToDefault)
{
Vector 3 rot = new Vector 3 (transform.parent.rotation.x, Quaternion.Slerp(transform.parent.rotation, defaultRotation, Time.deltaTime).Euler.y, transorm.parent.rotation.y);
transform.parent.EulerAngles = rot;
}
}
And just change the variable returnToDefault to true whenever you want it to go back. Otherwise, you are constantly fighting your code, which as your wrote it is always rotating it back to default.

Related

Movement weird problem with asteroids replica in unity

This is part of my code.
if (Input.GetKey(KeyCode.A) || Input.GetKey(KeyCode.LeftArrow))
{
_turnDirection = 1.0f;
}
else if (Input.GetKey(KeyCode.D) || Input.GetKey(KeyCode.RightArrow))
{
_turnDirection = -1.0f;
}
I have a weird problem: The player will turn left but wont turn right. IDk why.
if you want the full code i can provide that: https://pastebin.com/CJ0wAVi0
Your issue is with your FixedUpdate. Instead of only rotating when _turnDirection is greater than zero, try rotating whenever it is not equal to zero since _turnDirection can be negative.

How to move rotated knife(RigidBody2D) diagonally?

I am new to Unity and so far enjoy my journey. Right now I have accomplished my knife constant rotation within [-30;30] degrees range. However, after the user presses any key, my knife should be moving fast in the direction it currently faces.
How can I achieve the following behavior? I tried addForce, changing velocity, but no results... Perhaps it is even impossible to do?
Here my knife is facing the left angle and I would like to it to just move in that direction really fast. No fancy effects :)
Here is the initial knife position.
Here is source code:
public void HandleRotation()
{
if (transform.rotation.z >= 0.3f)
{
right = false;
}
else if (transform.rotation.z <= -0.3f)
{
right = true;
}
if (right)
{
begin = begin + 0.05f;
}
else
{
begin = begin - 0.05f;
}
var tiltAroundZ = begin * tiltAngle;
var target = Quaternion.Euler (0, 0, tiltAroundZ);
transform.rotation = Quaternion.Slerp(transform.rotation, target, Time.deltaTime * smooth);
}
Translate(transform.forward())? If forward is the wrong axis, you could try up or right.
There should also be a version of the Translate method that includes a space parameter, in this case you'd use Space.Self instead of Space.World, which it currently is defaulting to.

Unity: Ignore collision of a plateform if jump to it from below. Using ContactFilter & rigidBody.Cast()

I am able to avoid a collision between my player and my entire plateform with the use of contactFilter2D.SetLayerMask() + rigidBody2D.Cast(Vector2, contactFilter, ...);
But I don't find a way to avoid the collision only if my player try to acces to the plateform from below it (with a vertical jump).
I'm pretty sure I should use the contactFilter2D.setNormalAngle() (after specify the minAngle and maxAngle) but no matter the size of my angles, I can't pass threw it.
This is how I initialize my contactFilter2D.
protected ContactFilter2D cf;
void Start () {
cf.useTriggers = false;
cf.minNormalAngle = 0;
cf.maxNormalAngle = 180;
cf.SetNormalAngle(cf.minNormalAngle, cf.maxNormalAngle);
cf.useNormalAngle = true;
}
void Update () {
}
I use it with
count = rb.Cast(move, contactFilter, hitBuffer, distance + shellRadius);
Any ideas ? If you want more code, tell me. But I don't think it will be usefull to understand the matter.
unity actualy has a ready made component for this: it is a physics component called "Platform Effector 2D" if you drag and drop it on your platform it will immediately work the way you want, and it has adjustable settings for tweaking the parameters. hope this helps!

Moving something rotated on a custom pivot Unity

I've created an arm with a custom pivot in Unity which is essentially supposed to point wherever the mouse is pointing, regardless of the orientation of the player. Now, this arm looks weird when pointed to the side opposite the one it was drawn at, so I use SpriteRenderer.flipY = true to flip the sprite and make it look normal. I also have a weapon at the end of the arm, which is mostly fine as well. Now the problem is that I have a "FirePoint" at the end of the barrel of the weapon, and when the sprite gets flipped the position of it doesn't change, which affects particles and shooting position. Essentially, all that has to happen is that the Y position of the FirePoint needs to become negative, but Unity seems to think that I want the position change to be global, whereas I just want it to be local so that it can work with whatever rotation the arm is at. I've attempted this:
if (rotZ > 40 || rotZ < -40) {
rend.flipY = true;
firePoint.position = new Vector3(firePoint.position.x, firePoint.position.y * -1, firePoint.position.z);
} else {
rend.flipY = false;
firePoint.position = new Vector3(firePoint.position.x, firePoint.position.y * -1, firePoint.position.z);
}
But this works on a global basis rather than the local one that I need. Any help would be much appreciated, and I hope that I've provided enough information for this to reach a conclusive result. Please notify me should you need anything more. Thank you in advance, and have a nice day!
You can use RotateAround() to get desired behaviour instead of flipping stuff around. Here is sample code:
public class ExampleClass : MonoBehaviour
{
public Transform pivotTransform; // need to assign in inspector
void Update()
{
transform.RotateAround(pivotTransform.position, Vector3.up, 20 * Time.deltaTime);
}
}

Building/constructing buildings at runtime

I'm playing around with an FPS where I want my player(s) to be able to build/construct their own buildings from scratch. I've searched around for exisiting solutions/theories, but have so far been unable to find anything suitable to my needs. Please point me in the right direction if I've missed anything.
Where I am right now is that I have three prefabs; floor, wall and wall with a door opening. First I want to instantiate floor tiles which I then can put walls on, and hopefully being able to have the walls snap to the edges/corners of the floor tiles.
Can anyone please point me in the right direction for how to do this? Also, does my desired "work flow" at all make sense? Any pitfalls in there?
Thanks in advance!
UPDATE: Here's what I have in regards to instantiation prefabs, and while this works (except it's like I'm shooting walls), I would like the wall to snap to the corners/edges of the nearest floor (which has already been instantiated in the same fashion.
[RequireComponent (typeof (CharacterController))]
public class PlayerController : MonoBehaviour {
// Declare prefabs here
GameObject wallPrefab;
// Initialise variables before the game starts
void Awake () {
wallPrefab = (GameObject)Resources.Load( "WoodWall" );
}
// This happens every frame
void Update () {
if ( Input.GetButtonDown("Fire1") ) {
// Instantiate new wall
Instantiate( wallPrefab, cc.transform.position + cc.transform.forward + Vector3.up * 1.0f, wallPrefab.transform.rotation );
}
}
}
hmm... well one solution I can think of, is to have the wall raycast downwards in order to find a floor, then move to a predetermined position in relation to that floor (if it found any). Stick this in a script in the wall prefabs:
void Start()
{
var down = transform.TransformDirection (Vector3.down); //down might not actually be the down direction of your object, check to make sure
RaycastHit hit;
if (Physics.Raycast(transform.position, down, out hit) && hit.collider.gameObject.name == "myFloorName") //Maybe use tags here instead of name
{
Vector3 floorPos = hit.collider.gameObject.transform.position;
Vector3 floorSize = hit.collider.gameObject.transform.localScale;
this.transform.position = new Vector3(floorPos.x - floorSize.x/2, floorPos.y - this.tranform.localScale.y/2, floorPos.z); //These might need fiddling with to get right
}
}
void Update()
{
}
Vector3.down may not correspond to the down direction for the wall, since this can depend on the 3d model too, so you might need to fiddle with that. The position might also need fiddling with (this assumes that y corresponds to height, which might not be the case), but hopefully this gives you a rough idea of how it can be done. Also, if you don't know what the name of the floor object is, you could probably check by tags, which is probably easier.
If anything else needs clarifying, leave a comment and I'll get back to you