So I have an object that user can rotate with touch. If needed, here is the script for it:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SpinWithTaps : MonoBehaviour {
float lastX;
public float xDifference;
public float xDecreaseSpeed;
int xDirection = 1;
float lastY;
public float yDifference;
public float yDecreaseSpeed;
int yDirection = 1;
void Update()
{
//turn in y Axis
if (Input.GetMouseButtonDown(0)) xDifference = 0;
else if (Input.GetMouseButton(0))
{
xDifference = Mathf.Abs((lastX - Input.GetAxis("Mouse X")) * 1.8f);
if (lastX < Input.GetAxis("Mouse X"))
{
xDirection = -1;
transform.Rotate(Vector3.up, -xDifference, relativeTo: Space.World);
}
if (lastX > Input.GetAxis("Mouse X"))
{
xDirection = 1;
transform.Rotate(Vector3.up, xDifference, relativeTo: Space.World);
}
lastX = -Input.GetAxis("Mouse X");
}
else
{
if (xDifference > 0)
{
if (xDifference > 20) xDecreaseSpeed = 0.3f;
else if (xDifference > 15) xDecreaseSpeed = 0.23f;
else if (xDifference > 10) xDecreaseSpeed = 0.16f;
else if (xDifference > 5) xDecreaseSpeed = 0.09f;
else xDecreaseSpeed = 0.02f;
xDifference -= xDecreaseSpeed;
if (xDifference < 0) xDifference = 0;
}
if (xDifference < 0)
{
if (xDifference < 20) xDecreaseSpeed = 0.3f;
else if (xDifference < 15) xDecreaseSpeed = 0.23f;
else if (xDifference < 10) xDecreaseSpeed = 0.16f;
else if (xDifference < 5) xDecreaseSpeed = 0.09f;
else xDecreaseSpeed = 0.02f;
xDifference += xDecreaseSpeed;
if (xDifference > 0) xDifference = 0;
}
transform.Rotate(Vector3.up, xDifference * xDirection, relativeTo: Space.World);
}
//turn in x Axis
if (Input.GetMouseButtonDown(0)) yDifference = 0;
else if (Input.GetMouseButton(0))
{
yDifference = Mathf.Abs((lastY - Input.GetAxis("Mouse Y")) * 1.8f);
if (lastY < Input.GetAxis("Mouse Y"))
{
yDirection = 1;
transform.Rotate(Vector3.right, yDifference, relativeTo: Space.World);
}
if (lastY > Input.GetAxis("Mouse Y"))
{
yDirection = -1;
transform.Rotate(Vector3.right, -yDifference, relativeTo: Space.World);
}
lastY = -Input.GetAxis("Mouse Y");
}
else
{
if (yDifference > 0)
{
if (yDifference > 20) yDecreaseSpeed = 0.3f;
else if (yDifference > 15) yDecreaseSpeed = 0.23f;
else if (yDifference > 10) yDecreaseSpeed = 0.16f;
else if (yDifference > 5) yDecreaseSpeed = 0.09f;
else yDecreaseSpeed = 0.02f;
yDifference -= yDecreaseSpeed;
if (yDifference < 0) yDifference = 0;
}
if (yDifference < 0)
{
if (yDifference < 20) yDecreaseSpeed = 0.3f;
else if (yDifference < 15) yDecreaseSpeed = 0.23f;
else if (yDifference < 10) yDecreaseSpeed = 0.16f;
else if (yDifference < 5) yDecreaseSpeed = 0.09f;
else yDecreaseSpeed = 0.02f;
yDifference += yDecreaseSpeed;
if (yDifference > 0) yDifference = 0;
}
transform.Rotate(Vector3.right, yDifference * yDirection, relativeTo: Space.World);
}
}
I want to do something when the gameObject has rotated let's say... 90 degrees in total. Like so:
if (totalRotated >= 90)
{
//do something
}
How do I find totalRotated? Thanks.
Edit: Or what if I wanted to do something when it rotates 480° in total? Is there any way?
You can rotate along the x, y, or z axis.
if (gameObject.transform.rotation.x == 90) // You might want to use >= to check if it is greater than 90 in this case
{
// do something
}
Haha, I actually found a relatively easy solution.
I added this line of code to my Update function:
totalRotated += (yDifference + xDifference);
(and I created a float named totalRotated) and it's working really well.
Related
I was coding movement code for my game using this video: Movement code video.
Pardon my garbage code...
void Move(float dir,bool crouchFlag)
{
if(!crouchFlag)
{
if(Physics2D.OverlapCircle(OverheadChecker.position,CelingCirSize,gLayerMask))
{
crouchFlag = true;
}
}
Stand.enabled = !crouchFlag;
Stand2.enabled = !crouchFlag;
Croucher.enabled = crouchFlag;
#region Move & run
if (isGrounded && !crouchFlag && !isOnSlope)
{
Controller.XMove(dir,Speed,rb2d,velPower,acceleration,decceleration);
} else if (isGrounded && isOnSlope && canWalkOnSlope)
{
float TargetSpeed = -dir * Speed;
float TargetSpeedDif = TargetSpeed - rb2d.velocity.x;
float accelerRate = (Mathf.Abs(TargetSpeed) > 0.01f) ? airacceleration : airdecceleration;
float MoveDir = Mathf.Pow(Mathf.Abs(TargetSpeedDif) * accelerRate, velPower) * Mathf.Sign(TargetSpeedDif);
float MoveDirX = MoveDir * slopeNormalPerp.x * MultSlope;
float MoveDirY = MoveDir * slopeNormalPerp.y * MultSlope;
rb2d.AddForce(MoveDirX * Vector2.right);
rb2d.AddForce(MoveDirY * Vector2.up);
}
else if (!isGrounded)
{
float TargetSpeed = dir * Speed;
float TargetSpeedDif = TargetSpeed - rb2d.velocity.x;
float accelerRate = (Mathf.Abs(TargetSpeed) > 0.01f) ? airacceleration : airdecceleration;
float MoveDir = Mathf.Pow(Mathf.Abs(TargetSpeedDif) * accelerRate, velPower) * Mathf.Sign(TargetSpeedDif);
if (rb2d.velocity.y > 0 && !Input.GetButton("Jump"))
{
MoveDir = MoveDir * xJumpForce;
}
rb2d.AddForce(MoveDir * Vector2.right);
}else if (isGrounded && crouchFlag)
{
rb2d.sharedMaterial = noFriction;
float TargetSpeed = dir * CrouchSpeed;
float TargetSpeedDif = TargetSpeed - rb2d.velocity.x;
float accelerRate = (Mathf.Abs(TargetSpeed) > 0.01f) ? acceleration : Crouchdecceleration;
float MoveDir = Mathf.Pow(Mathf.Abs(TargetSpeedDif) * accelerRate, velPower) * Mathf.Sign(TargetSpeedDif);
rb2d.AddForce(MoveDir * Vector2.right);
}
if (isGrounded && Mathf.Abs(HorizontalValue) < 0.01f)
{
float amount = Mathf.Min(Mathf.Abs(rb2d.velocity.x), Mathf.Abs(fricAmount));
amount *= Mathf.Sign(rb2d.velocity.x);
rb2d.AddForce(Vector2.right * -amount, ForceMode2D.Impulse);
}
Vector3 CurrentScale = transform.localScale;
if(Right && dir > 0)
{
transform.localScale = new Vector3(1.4f, 1.4f
, 1);
Right = false;
}
else if (!Right == dir < 0)
{
transform.localScale = new Vector3(-1.4f, 1.4f, 1);
Right = true;
}
#endregion
}
Then I made slopes using a Sprite Shape Controller:
But, the character got stuck on the slopes when going up them, so I used this video for slopes:Fixing slopes video
Irrelevant code is removed:
private void SlopeCheck()
{
checkPos = transform.position - (Vector3)(new Vector2(0.0f, colliderSize.y / 2));
SlopeCheckHorizontal(checkPos);
SlopeCheckVertical(checkPos);
}
private void SlopeCheckHorizontal(Vector2 checkPos)
{
RaycastHit2D slopeHitFront = Physics2D.Raycast(checkPos, transform.right, slopeCheckDistance, gLayerMask);
RaycastHit2D slopeHitBack = Physics2D.Raycast(checkPos, -transform.right, slopeCheckDistance, gLayerMask);
if (slopeHitFront)
{
isOnSlope = true;
slopeSideAngle = Vector2.Angle(slopeHitFront.normal, Vector2.up);
}
else if (slopeHitBack)
{
isOnSlope = true;
slopeSideAngle = Vector2.Angle(slopeHitBack.normal, Vector2.up);
}
else
{
slopeSideAngle = 0.0f;
isOnSlope = false;
}
}
private void SlopeCheckVertical(Vector2 checkPos)
{
RaycastHit2D hit = Physics2D.Raycast(checkPos, Vector2.down, slopeCheckDistance, gLayerMask);
if (hit)
{
slopeNormalPerp = Vector2.Perpendicular(hit.normal).normalized;
slopeDownAngle = Vector2.Angle(hit.normal, Vector2.up);
if(slopeDownAngle != lastSlopeAngle)
{
isOnSlope = true;
}
lastSlopeAngle = slopeDownAngle;
Debug.DrawRay(hit.point, slopeNormalPerp, Color.blue);
Debug.DrawRay(hit.point, hit.normal, Color.green);
}
if (slopeDownAngle > maxSlopeAngle || slopeSideAngle > maxSlopeAngle)
{
canWalkOnSlope = false;
}
else
{
canWalkOnSlope = true;
}
if (isOnSlope && canWalkOnSlope && HorizontalValue == 0.0f)
{
rb2d.sharedMaterial = fullFriction;
}
else
{
rb2d.sharedMaterial = noFriction;
}
}
void Update()
{
if(slopeDownAngle != 0)
{
isOnSlope = true;
} else {
isOnSlope = false;
}
if (CanMove() == true){
HorizontalValue = Input.GetAxisRaw("Horizontal");
}
}
void FixedUpdate()
{
Gcheck();
Move(HorizontalValue, Crouch);
SlopeCheck();
}
Rigidbody>
Mass:0.5
BodyType: Dynamic
LinearDrag: 0
AngularDrag: 0
Gravity: 11
FreezeRotation: Only Z axis
::Friction Is Handled In The Movement Code::
But, when I finished the character got stuck again,
so I tried multiplying the slopeNormalPerp by a variable(MultSlope) and he just bounced up and down if made made it too high and if it was too low nothing happened.
I tried messing with varibles such as the ground-checking circles size, various colliders, the aforementioned MultSlope ,and slopeCheckDistance...
Nothing Helped...
I've been working on this for 7 months(with breaks working on other code) and I have improved greatly in coding, but I still can't fix it.
I tried messing with every relevant variable, watching the video many time, downloading and copy-pasting the code ,and following other tutorials of the slope code, No Dice.
I need help with trajectory prediction on mobile.
I'm able to do that on PC using the mouse, but I'm not able to do that with touch functions on mobile.
I've the dot that I copy on the start, and while I'm dragging the ball I want to calculate my trajectory.
After touch will end I will destroy these dots.
As I said I'm able to do it using Input.GetMouseButton/Up/Down but I'm not able to do that using touch function.
Here is my code:
private void Update()
{
//if (Input.touchCount > 0)
//{
Touch touch = Input.GetTouch(0);
if (touch.phase == TouchPhase.Began)
{
startPosition = Input.GetTouch(0).position;
for (int i = 0; i < number; i++)
{
trajectoryDots[i] = Instantiate(trajectoryDot, gameObject.transform);
}
}
if (Input.touchCount > 0)
{
for (int i = 0; i < number; i++)
{
trajectoryDots[i].transform.position = calculatePosition(i * 0.1f);
}
}
if (touch.phase == TouchPhase.Ended)
{
for (int i = 0; i < number; i++)
{
Destroy(trajectoryDots[i]);
}
endPoisiton = Input.GetTouch(0).position;
force = startPosition - endPoisiton;
ballRigid.gravityScale = 1;
ballRigid.velocity = new Vector2(force.x * power, force.y * power);
}
//}
}
private Vector2 calculatePosition(float elapsedTime)
{
return new Vector2(endPoisiton.x, endPoisiton.y) +
new Vector2(force.x * power, force.y * power) * elapsedTime +
0.5f * Physics2D.gravity * elapsedTime * elapsedTime;
}
The code I used for mouse input
if (Input.GetMouseButtonDown(0))
{ //click
startPos = gameObject.transform.position;
for (int i = 0; i < number; i++)
{
trajectoryDots[i] = Instantiate(trajectoryDot, gameObject.transform);
}
}
if (Input.GetMouseButton(0))
{ //drag
endPos = Camera.main.ScreenToWorldPoint(Input.mousePosition) + new Vector3(0, 0, 10);
gameObject.transform.position = endPos;
forceAtPlayer = endPos - startPos;
for (int i = 0; i < number; i++)
{
trajectoryDots[i].transform.position = calculatePosition(i * 0.1f);
}
}
if (Input.GetMouseButtonUp(0))
{ //leave
rigidbody.gravityScale = 1;
rigidbody.velocity = new Vector2(-forceAtPlayer.x * forceFactor, -forceAtPlayer.y * forceFactor);
for (int i = 0; i < number; i++)
{
Destroy(trajectoryDots[i]);
}
}
So after little changes it's much better, I' am getting closer to what i want there are still some glitches i guess because of touch.moved so when I' am on display with my finger and do only little moves ball is jumping on the screen
Here is the code
private void Update()
{
if (Input.touchCount > 0)
{
var touch = Input.GetTouch(0);
switch (touch.phase)
{
case TouchPhase.Began:
initPosition = gameObject.transform.position;
startPosition = cam.ScreenToWorldPoint(touch.position) + new Vector3(0, 0, 10);
for (int i = 0; i < number; i++)
{
trajectoryDots[i] = Instantiate(trajectoryDot, gameObject.transform);
trajectoryDots[i].transform.position = calculatePosition(i * 0.1f);
}
break;
case TouchPhase.Moved:
endPosition = Camera.main.ScreenToWorldPoint(touch.position) + new Vector3(0, 0, 10);
gameObject.transform.position = initPosition;
force = startPosition - endPosition;
for (int i = 0; i < number; i++)
{
trajectoryDots[i].transform.position = calculatePosition(i * 0.1f);
}
break;
case TouchPhase.Ended:
ballRigid.gravityScale = 1;
ballRigid.velocity = new Vector2(force.x * power, force.y * power);
for (int i = 0; i < number; i++)
{
Destroy(trajectoryDots[i]);
}
break;
}
}
}
private Vector2 calculatePosition(float elapsedTime)
{
return new Vector2(initPosition.x, initPosition.y) +
new Vector2(force.x * power, force.y * power) * elapsedTime +
0.5f * Physics2D.gravity * elapsedTime * elapsedTime;
}
Ok i have final soution and it's working correctly
private void Update()
{
if (Input.touchCount > 0)
{
var touch = Input.GetTouch(0);
switch (touch.phase)
{
case TouchPhase.Began:
initPosition = gameObject.transform.position;
startPosition = cam.ScreenToWorldPoint(touch.position) + new Vector3(0, 0, 10);
for (int i = 0; i < number; i++)
{
trajectoryDots[i] = Instantiate(trajectoryDot, gameObject.transform);
trajectoryDots[i].transform.position = calculatePosition(i * 0.1f);
}
break;
case TouchPhase.Ended:
ballRigid.gravityScale = 1;
ballRigid.velocity = new Vector2(force.x * power, force.y * power);
for (int i = 0; i < number; i++)
{
Destroy(trajectoryDots[i]);
}
break;
}
endPosition = Camera.main.ScreenToWorldPoint(touch.position) + new Vector3(0, 0, 10);
gameObject.transform.position = initPosition;
force = startPosition - endPosition;
for (int i = 0; i < number; i++)
{
trajectoryDots[i].transform.position = calculatePosition(i * 0.1f);
}
}
}
private Vector2 calculatePosition(float elapsedTime)
{
return new Vector2(initPosition.x, initPosition.y) +
new Vector2(force.x * power, force.y * power) * elapsedTime +
0.5f * Physics2D.gravity * elapsedTime * elapsedTime;
}
So just taking your mouse code and convert it to touch code it might look like
if(Input.touchCount > 0)
{
var touch = Input.GetTouch(0);
switch(touch.phase)
{
case TouchPhase.Began:
// Note: to be more accurate you actually probably would
// rather also here use ScreenToWorldPoint on the touch.position
// same way as later. Otherwise you might allways get a force even if touch wasn't moved at all
//startPos = transform.position;
startPos = Camera.main.ScreenToWorldPoint(touch.position) + new Vector3(0, 0, 10);
for (int i = 0; i < number; i++)
{
trajectoryDots[i] = Instantiate(trajectoryDot, gameObject.transform);
trajectoryDots[i].transform.position = calculatePosition(i * 0.1f);
}
break;
case TouchPhase.Moved:
// These were missing in your touch version
// You did it only in the end so there were no preview trajectory
// And note that also touch is in pixel screenspace so if you
// want to use world positions you need to convert them just the same as for mouse input!
endPos = Camera.main.ScreenToWorldPoint(touch.position) + new Vector3(0, 0, 10);
transform.position = endPos;
force = endPos - startPos;
for (int i = 0; i < number; i++)
{
trajectoryDots[i].transform.position = calculatePosition(i * 0.1f);
}
break;
case TouchPhase.Ended:
rigidbody.gravityScale = 1;
// Not sure why but in your mouse code you used a negative force here
// but in this case your trajectory would have been wrong since there you didn't use negative values...
rigidbody.velocity = force * forceFactor;
for (int i = 0; i < number; i++)
{
Destroy(trajectoryDots[i]);
}
break;
}
}
Btw the calculate method gets better to read like
private Vector2 calculatePosition(float elapsedTime)
{
return endPoisiton
+ force * power * elapsedTime
+ Physics2D.gravity * 0.5f * elapsedTime * elapsedTime;
}
Note: Typed on smartphone but I hope the idea gets clear
So basically what i am trying to do is create an animation script that does not just take simple direction like Up(0,1),Down(0,-1),Left(-1,0),Right(1,0)(Those numbers being vectors) but to have range of directions for to fill in the gap between those directions and play the more dominant direction Up,Down,Left,Right.
So each quarter section below to be set to an animation.
I have created a few scripts to try and achieve this i came up with one that wasn't perfect but it did work when dragging the enemies around in the scene editor while the game was running. When using their movements scripts for their movement it did not work. The animation script is below and underneath that how i move the enemies.
Below would be how i calculate the direction the enemy was moving:
IEnumerator directionFinder()
{
// while (true)
//{
Vector3 previousPosition = transform.position;
yield return new WaitForSeconds(1/10);
currentPosition = transform.position;
currentPosition.x = currentPosition.x - previousPosition.x;
currentPosition.y = currentPosition.y - previousPosition.y;
currentPosition.z = 0f;
angle = (Mathf.Atan2(currentPosition.y, currentPosition.x) * Mathf.Rad2Deg);
if(angle < 0)
{
angle = Mathf.Abs(angle) + 180;
}
// }
}
Then this is what calculated which animation to use:
void animationDirection()
{
if (angle == 0)
{
anim.SetInteger("Move", currentAnim);
}
if (angle > 45 && angle <135)//W
{
anim.SetInteger("Move", 1);
currentAnim = 1;
}
else if (angle > 135 && angle < 225)//A
{
anim.SetInteger("Move", 2);
currentAnim = 2;
}
else if (angle > 225 && angle < 315)//S
{
anim.SetInteger("Move", 3);
currentAnim = 3;
}
else if((angle < 45 && angle >= 0) || (angle > 315 && angle <= 0))//D
{
anim.SetInteger("Move", 4);
currentAnim = 4;
}
}
This using the code below it would move to the waypoint that was selected via the rest of my code that would just loop through a set of waypoints changing the waypoint when it arrived at one.
transform.position = Vector2.MoveTowards(transform.position, waypoints[waypointNUmber].transform.position, speed * Time.deltaTime);
Below I tried another way but it did not work and created weird buggy animations:
IEnumerator directionalAnimation()
{
while (true)
{
Debug.Log("working");
Vector2 previousPosition = transform.position;
yield return new WaitForSeconds(1/10);
Vector2 currentPosition = transform.position;
Vector2 direction = (previousPosition - currentPosition).normalized;
float moveX = direction.x;
float moveY = direction.y;
if (moveX < 0)
{
moveXNegative = true;
moveX = Mathf.Abs(moveX);
}
if (moveY < 0)
{
moveYNegative = true;
moveY = Mathf.Abs(moveY);
}
if (direction.magnitude != 0)
{
if (moveX > moveY)
{
if (moveXNegative)
{
//left
Walking = true;
anim.SetInteger("Move", 2);
moveYNegative = false;
}
else
{
//Right
Walking = true;
anim.SetInteger("Move", 4);
moveYNegative = false;
}
}
else if (moveY > moveX)
{
if (moveYNegative)
{
//Down
Walking = true;
anim.SetInteger("Move", 3);
}
else
{
//Up
Walking = true;
anim.SetInteger("Move", 1);
}
}
}
else
{
source.Pause();
Walking = false;
}
if (Walking)
{
source.UnPause();
}
}
}
I am trying to make a mouse-oriented 3d Agar.io. Right now, I am working on the basic movement and camera readjustments. I want the camera to be able to rotate around an object, but here is the catch: I want to use only the mouse to move the object and camera, and rotate the camera. I, however, was able to configure the logic of this using the distance formula twice and the law of cosines. I based this on the origin point (0, 0). I am positive that there is nothing wrong with the process that I did; however, I know that the way it is being outputted is wrong.
Every time you move the mouse left or right, I want the camera to rotate immediately after. I tried using a FixedUpdate and LateUpdate event to try to make this happen but both did not succeed. The code I tried using for the camera to rotate is this:
void LateUpdate ()
{
// Move Camera
transform.position = new Vector3(camX, 10.5f, camZ);
//Rotate Camera
//transform.eulerAngles = getRotation;
//transform.eulerAngles = Vector3.MoveTowards(currentRotation, getRotation, speed * Time.deltaTime);
}
The full code I have (updated):
public class CameraController : MonoBehaviour {
public float speed;
public GameObject player;
private Ray ray;
private RaycastHit hit;
private Vector3 mousePos;
private float camX;
private float camZ;
private float getA;
private float getB;
private float getC;
private float getAngle;
private Vector3 currentRotation;
private Vector3 getRotation;
void Start ()
{
}
void FixedUpdate()
{
}
void LateUpdate ()
{
if (PlayerController.movedPlayer)
{
if (Physics.Raycast(ray, out hit))
{
mousePos = new Vector3(hit.point.x, 1.3f, hit.point.z);
}
// MouseZ
if (mousePos.z >= player.transform.position.z)
{
// Camera Follow Z+
if ((player.transform.position.z >= 0 && player.transform.position.x >= 0) &&
player.transform.position.z >= player.transform.position.x)
{
camZ = player.transform.position.z - 10;
camX = 0;
}
else if ((player.transform.position.z >= 0 && player.transform.position.x < 0) &&
player.transform.position.z >= -player.transform.position.x)
{
camZ = player.transform.position.z - 10;
camX = 0;
}
else if ((player.transform.position.z >= 0 && player.transform.position.x >= 0) &&
player.transform.position.z < player.transform.position.x)
{
camX = player.transform.position.x - 10;
camZ = 0;
}
else if ((player.transform.position.z >= 0 && player.transform.position.x < 0) &&
player.transform.position.z < -player.transform.position.x)
{
camX = player.transform.position.x + 10;
camZ = 0;
}
// Camera Follow Z-
if ((player.transform.position.z < 0 && player.transform.position.x >= 0) &&
-player.transform.position.z >= player.transform.position.x)
{
camZ = player.transform.position.z + 10;
camX = 0;
}
else if ((player.transform.position.z < 0 && player.transform.position.x < 0) &&
-player.transform.position.z >= -player.transform.position.x)
{
camZ = player.transform.position.z + 10;
camX = 0;
}
else if ((player.transform.position.z < 0 && player.transform.position.x >= 0) &&
-player.transform.position.z < player.transform.position.x)
{
camX = player.transform.position.x - 10;
camZ = 0;
}
else if ((player.transform.position.z < 0 && player.transform.position.x < 0) &&
-player.transform.position.z < -player.transform.position.x)
{
camX = player.transform.position.x + 10;
camZ = 0;
}
}
//PlayerZ
else if (mousePos.z < player.transform.position.z)
{
// Camera Follow Z+
if ((player.transform.position.z >= 0 && player.transform.position.x >= 0) &&
player.transform.position.z >= player.transform.position.x)
{
camZ = player.transform.position.z + 10;
camX = 0;
}
else if ((player.transform.position.z >= 0 && player.transform.position.x < 0) &&
player.transform.position.z >= -player.transform.position.x)
{
camZ = player.transform.position.z + 10;
camX = 0;
}
else if ((player.transform.position.z >= 0 && player.transform.position.x >= 0) &&
player.transform.position.z < player.transform.position.x)
{
camX = player.transform.position.x + 10;
camZ = 0;
}
else if ((player.transform.position.z >= 0 && player.transform.position.x < 0) &&
player.transform.position.z < -player.transform.position.x)
{
camX = player.transform.position.x - 10;
camZ = 0;
}
// Camera Follow Z-
if ((player.transform.position.z < 0 && player.transform.position.x >= 0) &&
-player.transform.position.z >= player.transform.position.x)
{
camZ = player.transform.position.z - 10;
camX = 0;
}
else if ((player.transform.position.z < 0 && player.transform.position.x < 0) &&
-player.transform.position.z >= -player.transform.position.x)
{
camZ = player.transform.position.z - 10;
camX = 0;
}
else if ((player.transform.position.z < 0 && player.transform.position.x >= 0) &&
-player.transform.position.z < player.transform.position.x)
{
camX = player.transform.position.x + 10;
camZ = 0;
}
else if ((player.transform.position.z < 0 && player.transform.position.x < 0) &&
-player.transform.position.z < -player.transform.position.x)
{
camX = player.transform.position.x - 10;
camZ = 0;
}
}
// Make Triangle
getA = mousePos.x - player.transform.position.x;
getB = mousePos.z - player.transform.position.z;
getC = Mathf.Sqrt(Mathf.Pow((getA), 2) + Mathf.Pow((getB), 2));
// Get Rotating Angle.
if (getA == 0 && getB >= 0)
{
getAngle = 0;
}
else if (getA == 0 && getB < 0)
{
getAngle = 180;
}
else if (getB == 0 && getA >= 0)
{
getAngle = 90;
}
else if (getB == 0 && getA < 0)
{
getAngle = 270;
}
else
{
if (getA > 0)
{
getAngle = Mathf.Acos((Mathf.Pow((getB), 2) + Mathf.Pow((getC), 2) - Mathf.Pow((getA), 2)) /
(2 * (getB) * (getC))) * Mathf.Rad2Deg;
}
else if (getA < 0)
{
getAngle = -Mathf.Acos((Mathf.Pow((getB), 2) + Mathf.Pow((getC), 2) - Mathf.Pow((getA), 2)) /
(2 * (getB) * (getC))) * Mathf.Rad2Deg;
}
//getAngle = Mathf.Asin(getA * Mathf.Sin(90) / getC);
//Debug.Log("A: " + getA + " B: " + getB + " C: " + getC + " Angle: " + getAngle);
}
// Set Rotating Angle
currentRotation = transform.eulerAngles;
getRotation = new Vector3(45f, getAngle, 0f);
}
// Move Camera
transform.position = new Vector3(camX, 10.5f, camZ);
//Rotate Camera
//transform.eulerAngles = getRotation;
transform.eulerAngles = Vector3.MoveTowards(currentRotation, getRotation, speed * Time.deltaTime);
}
}
Let me elaborate on the code. I wanted the camera to face toward the origin when the mouse was the closest to it and vise versa. I am having some trouble with this because I don't think I set it up right. My attempt at trying to fix this was using reverse logic (i.e. when the mouse is closer to the origin the camera is the furthest away from the origin [mouse -> object -> camera]. The opposite would be true if the mouse was the furthest from the origin [camera -> object -> mouse].)
Now that you know some of the issues I am having, here is what I need answered (I would prefer you write a solution and tell me how it fixes the problem.): How do I fix the camera rotation so it rotates immediately when the mouse moves, and how can I specify whether the mouse is closer, or not, to the origin?
Update: I moved all the code to LateUpdate because that's when you should do your camera algorithms. I also "tried" to simplify the mouse location part, so it isn't so redundant. I also have a link to a screen capture of my project: https://gyazo.com/2f5ee8f94c0bc55bbdeaeafa8a8b35f4
I found the solution:
transform.rotation = Quaternion.RotateTowards(transform.rotation, getRotation, speed * Time.deltaTime);
I have made a game in unity which have multiple scenes of different level in which user have to select a colored block to go the next level but i want my code to be in a single scene is there a way i can convert my multi scene game into a single scene .
Code for level 1 grid base is
public IEnumerator Start() {
grid = new GameObject[ySize, xSize];
float x = xStart;
float y = yStart;
ScreenRandom = Random.Range(0, 3);
if (ScreenRandom == 0)
{
img.color = UnityEngine.Color.red;
text.text = "Select all the Red Objects";
yield return new WaitForSeconds(time);
Destroy(img);
Destroy(text);
int check = 1;
for (int i = 0; i < ySize; i++)
{
for (int j = 0; j < xSize; j++)
{
if (check <= 1)
{
GameObject rblock = Instantiate(RedPrefabs[Random.Range(0, 1)]) as GameObject;
rblock.GetComponent<RectTransform>().anchoredPosition = new Vector2(x, y);
rblock.transform.localScale = new Vector3(1.0f, 1.0f, 1.0f) * scale;
rblock.transform.SetParent(canvas.transform);
grid[i, j] = rblock;
CountRed++;
}
else {
GameObject block = Instantiate(NonRedPrefab[Random.Range(0, 2)]) as GameObject;
block.GetComponent<RectTransform>().anchoredPosition = new Vector2(x, y);
block.transform.localScale = new Vector3(1.0f, 1.0f, 1.0f) * scale;
block.transform.SetParent(canvas.transform);
grid[i, j] = block;
}
check++;
x += xWidth * space;
}
y -= yHeight * space;
x = xStart;
}
}
if (ScreenRandom == 1)
{
img.color = UnityEngine.Color.blue;
text.text = "Select all the Blue Objects";
yield return new WaitForSeconds(time);
Destroy(img);
Destroy(text);
int check = 1;
for (int i = 0; i < ySize; i++)
{
for (int j = 0; j < xSize; j++)
{
if (check <= 1)
{
GameObject rblock = Instantiate(BluePrefabs[Random.Range(0, 1)]) as GameObject;
rblock.GetComponent<RectTransform>().anchoredPosition = new Vector2(x, y);
rblock.transform.localScale = new Vector3(1.0f, 1.0f, 1.0f) * scale;
rblock.transform.SetParent(canvas.transform);
grid[i, j] = rblock;
CountBlue++;
}
else {
GameObject block = Instantiate(NonBluePrefab[Random.Range(0, 2)]) as GameObject;
block.GetComponent<RectTransform>().anchoredPosition = new Vector2(x, y);
block.transform.localScale = new Vector3(1.0f, 1.0f, 1.0f) * scale;
block.transform.SetParent(canvas.transform);
grid[i, j] = block;
}
check++;
x += xWidth * space;
}
y -= yHeight * space;
x = xStart;
}
}
if (ScreenRandom == 2)
{
img.color = UnityEngine.Color.yellow;
text.text = "Select all the Yellow Objects";
yield return new WaitForSeconds(time);
Destroy(img);
Destroy(text);
int check = 1;
for (int i = 0; i < ySize; i++)
{
for (int j = 0; j < xSize; j++)
{
if (check <= 1)
{
GameObject rblock = Instantiate(YellowPrefabs[Random.Range(0, 1)]) as GameObject;
rblock.GetComponent<RectTransform>().anchoredPosition = new Vector2(x, y);
rblock.transform.localScale = new Vector3(1.0f, 1.0f, 1.0f) * scale;
rblock.transform.SetParent(canvas.transform);
grid[i, j] = rblock;
CountYellow++;
}
else {
GameObject block = Instantiate(NonYellowPrefab[Random.Range(0, 2)]) as GameObject;
block.GetComponent<RectTransform>().anchoredPosition = new Vector2(x, y);
block.transform.localScale = new Vector3(1.0f, 1.0f, 1.0f) * scale;
block.transform.SetParent(canvas.transform);
grid[i, j] = block;
}
check++;
x += xWidth * space;
}
y -= yHeight * space;
x = xStart;
}
}
}
Code to check and Load Level 2 is:
void Update () {
screen = GridControl.ScreenRandom;
if (Input.GetMouseButtonDown(0))
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (screen == 0)
{
if (Physics.Raycast(ray, out hit))
{
if (hit.collider.tag == "BlueBlock")
{
Destroy(hit.transform.gameObject);
print("GameOver");
Application.LoadLevel(0);
}
if (hit.collider.tag == "RedBlock")
{
RedCount++;
Destroy(hit.transform.gameObject);
Correct++;
Score.text = " " + Correct;
if (RedCount == GridControl.CountRed)
{
print("Next Level");
Application.LoadLevel(3);
}
}
if (hit.collider.tag == "YellowBlock")
{
Destroy(hit.transform.gameObject);
print("GameOver");
Application.LoadLevel(0);
}
}
}
if (screen == 1)
{
if (Physics.Raycast(ray, out hit))
{
if (hit.collider.tag == "BlueBlock")
{
BlueCount++;
Destroy(hit.transform.gameObject);
Correct++;
Score.text = " " + Correct;
if (BlueCount == GridControl.CountBlue)
{
print("Next Level");
Application.LoadLevel(3);
}
}
if (hit.collider.tag == "RedBlock")
{
Destroy(hit.transform.gameObject);
print("GameOver");
Application.LoadLevel(0);
}
if (hit.collider.tag == "YellowBlock")
{
Destroy(hit.transform.gameObject);
print("GameOver");
Application.LoadLevel(0);
}
}
}
if (screen == 2)
{
if (Physics.Raycast(ray, out hit))
{
if (hit.collider.tag == "BlueBlock")
{
Destroy(hit.transform.gameObject);
print("GameOver");
Application.LoadLevel(0);
}
if (hit.collider.tag == "RedBlock")
{
Destroy(hit.transform.gameObject);
print("Game Over");
Application.LoadLevel(0);
}
if (hit.collider.tag == "YellowBlock")
{
YellowCount++;
Destroy(hit.transform.gameObject);
Correct++;
Score.text = " " + Correct;
if (YellowCount == GridControl.CountYellow)
{
print("Next Level");
Application.LoadLevel(3);
}
}
}
Code for Level 2 GridBase is;
public void Start()
{
grid = new GameObject[ySize, xSize];
ScreenRandom = GridControl.ScreenRandom;
float x = xStart;
float y = yStart;
if (ScreenRandom == 0)
{
int check = 1;
for (int i = 0; i < ySize; i++)
{
for (int j = 0; j < xSize; j++)
{
if (check <= 2)
{
GameObject rblock = Instantiate(RedPrefabs[Random.Range(0, 1)]) as GameObject;
rblock.GetComponent<RectTransform>().anchoredPosition = new Vector2(x, y);
rblock.transform.localScale = new Vector3(1.0f, 1.0f, 1.0f) * scale;
rblock.transform.SetParent(canvas.transform);
grid[i, j] = rblock;
CountRed++;
}
else {
GameObject block = Instantiate(NonRedPrefab[Random.Range(0, 2)]) as GameObject;
block.GetComponent<RectTransform>().anchoredPosition = new Vector2(x, y);
block.transform.localScale = new Vector3(1.0f, 1.0f, 1.0f) * scale;
block.transform.SetParent(canvas.transform);
grid[i, j] = block;
}
check++;
x += xWidth * space;
}
y -= yHeight * space;
x = xStart;
}
}
if (ScreenRandom == 1)
{
int check = 1;
for (int i = 0; i < ySize; i++)
{
for (int j = 0; j < xSize; j++)
{
if (check <= 2)
{
GameObject rblock = Instantiate(BluePrefabs[Random.Range(0, 1)]) as GameObject;
rblock.GetComponent<RectTransform>().anchoredPosition = new Vector2(x, y);
rblock.transform.localScale = new Vector3(1.0f, 1.0f, 1.0f) * scale;
rblock.transform.SetParent(canvas.transform);
grid[i, j] = rblock;
CountBlue++;
}
else {
GameObject block = Instantiate(NonBluePrefab[Random.Range(0, 2)]) as GameObject;
block.GetComponent<RectTransform>().anchoredPosition = new Vector2(x, y);
block.transform.localScale = new Vector3(1.0f, 1.0f, 1.0f) * scale;
block.transform.SetParent(canvas.transform);
grid[i, j] = block;
}
check++;
x += xWidth * space;
}
y -= yHeight * space;
x = xStart;
}
}
if (ScreenRandom == 2)
{
int check = 1;
for (int i = 0; i < ySize; i++)
{
for (int j = 0; j < xSize; j++)
{
if (check <= 2)
{
GameObject rblock = Instantiate(YellowPrefabs[Random.Range(0, 1)]) as GameObject;
rblock.GetComponent<RectTransform>().anchoredPosition = new Vector2(x, y);
rblock.transform.localScale = new Vector3(1.0f, 1.0f, 1.0f) * scale;
rblock.transform.SetParent(canvas.transform);
grid[i, j] = rblock;
CountYellow++;
}
else {
GameObject block = Instantiate(NonYellowPrefab[Random.Range(0, 2)]) as GameObject;
block.GetComponent<RectTransform>().anchoredPosition = new Vector2(x, y);
block.transform.localScale = new Vector3(1.0f, 1.0f, 1.0f) * scale;
block.transform.SetParent(canvas.transform);
grid[i, j] = block;
}
check++;
x += xWidth * space;
}
y -= yHeight * space;
x = xStart;
}
}
}
To start I don't know why would you do that. Technically that is the whole point of having scenes. But still what you could do is put everything (Level 1 and 2) in one scene and then position and disable whatever belongs to Level 2 outside the camera. Then instead of calling Application.LoadLevel I would call a function that will move everything that belongs to Level 1 out of the screen and at the same time moves Level 2 into the screen. If I where you I would group all the objects of one level as child of another GameObject (maybe called LevelX), that way it will be easier to move everything at once. This will even give you nice slide in transition between levels. If you don't want the transition just change the positions instantly.
Be carefull because depending on the amount of levels you could have serious performance issues.
You could use a prefab for the colored blocks and drag it into your different level scenes. If you now attach your behaviour script (managing what happens if a raycast hits it) to your prefab, all instances in all levels will have the same logic. That way you can reuse the same code base for different levels.