When the game starts, a random waypoint is selected from an array. The camera should then rotate to face the selected random waypoint and start moving towards it.
Once the camera has reached the waypoint, it should wait 3 seconds before rotating to face and move towards the next random waypoint.
The problem I have is in Start(). The camera does not rotate to face the first waypoint before it starts moving towards it. Instead, it moves towards the first waypoint backwards. Then, when it reaches the waypoint, it waits 3 seconds to rotate and move towards the next waypoint.
It's working fine except that the camera does not rotate to face the first selected random waypoint. It's moving to it backward without first rotating to face it.
Here's my code:
The waypoints script
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Waypoints : MonoBehaviour
{
public GameObject[] waypoints;
public GameObject player;
public float speed = 5;
public float WPradius = 1;
public LookAtCamera lookAtCam;
private int current = 0;
private bool rot = false;
public void Init()
{
waypoints = GameObject.FindGameObjectsWithTag("Target");
if(waypoints.Length > 0)
{
StartCoroutine(RotateFacingTarget(waypoints[UnityEngine.Random.Range(0, waypoints.Length)].transform));
}
}
void Update()
{
if (waypoints.Length > 0)
{
if (Vector3.Distance(waypoints[current].transform.position, transform.position) < WPradius)
{
current = UnityEngine.Random.Range(0, waypoints.Length);
rot = false;
StartCoroutine(RotateFacingTarget(waypoints[current].transform));
if (current >= waypoints.Length)
{
current = 0;
}
}
if (rot)
transform.position = Vector3.MoveTowards(transform.position, waypoints[current].transform.position, Time.deltaTime * speed);
}
}
IEnumerator RotateFacingTarget(Transform target)
{
yield return new WaitForSeconds(3);
lookAtCam.target = target;
rot = true;
}
}
The look at camera script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class LookAtCamera : MonoBehaviour
{
//values that will be set in the Inspector
public Transform target;
public float RotationSpeed;
//values for internal use
private Quaternion _lookRotation;
private Vector3 _direction;
// Update is called once per frame
void Update()
{
//find the vector pointing from our position to the target
if (target)
{
_direction = (target.position - transform.position).normalized;
//create the rotation we need to be in to look at the target
_lookRotation = Quaternion.LookRotation(_direction);
//rotate us over time according to speed until we are in the required rotation
transform.rotation = Quaternion.Slerp(transform.rotation, _lookRotation, Time.deltaTime * RotationSpeed);
}
}
}
How can I fix this?
Let's assume that Waypoints.Init() is being called and your waypoints variable has an array of 3.
Waypoints.Init() starts a coroutine
Your coroutine waits 3 seconds
After 3 seconds, you set your camera target which Slerps to face the position
Update on its first frame says waypoints.Length > 0 == true
It's not close to its target, and rot is false, so it does not move
Now, you're waiting 3 seconds, not rotating, and not moving.
Your coroutine's 3 second wait time is up and starts the rotation toward your target
rot is now true at the start of your rotation, so your Update method starts moving toward the target as well
It would seem that your logic is off in how the order of operations works. If it needs to act as you describe, I suggest that you operate on the target differently.
I've implemented the following using an enum:
Waypoints
public class Waypoints : MonoBehaviour
{
private GameObject[] waypoints;
private Transform currentWaypoint;
private enum CameraState
{
StartRotating,
Rotating,
Moving,
Waiting
}
private CameraState cameraState;
public GameObject player;
public float speed = 5;
public float WPradius = 1;
public LookAtCamera lookAtCam;
private int current = 0;
private bool isCameraRotating = false;
void Start()
{
cameraState = CameraState.StartRotating;
}
void Update()
{
switch (cameraState)
{
// This state is used as a trigger to set the camera target and start rotation
case CameraState.StartRotating:
{
// Sanity check in case the waypoint array was set to length == 0 between states
if (waypoints.Length == 0)
break;
// Tell the camera to start rotating
currentWaypoint = waypoints[UnityEngine.Random.Range(0, waypoints.Length)].transform;
lookAtCam.target = currentWaypoint;
cameraState = CameraState.Rotating;
break;
}
// This state only needs to detect when the camera has completed rotation to start movement
case CameraState.Rotating:
{
if (lookAtCam.IsFinishedRotating)
cameraState = CameraState.StartMoving;
break;
}
case CameraState.Moving:
{
// Move
transform.position = Vector3.MoveTowards(transform.position, currentWaypoint.position, Time.deltaTime * speed);
// Check for the Waiting state
if (Vector3.Distance(currentWaypoint.position, transform.position) < WPradius)
{
// Set to waiting state
cameraState = CameraState.Waiting;
// Call the coroutine to wait once and not in CameraState.Waiting
// Coroutine will set the next state
StartCoroutine(WaitForTimer(3));
}
break;
}
case CameraState.Waiting:
// Do nothing. Timer has already started
break;
}
}
IEnumerator WaitForTimer(float timer)
{
yield return new WaitForSeconds(timer);
cameraState = CameraState.StartRotating;
}
public void RefreshWaypoints()
{
waypoints = GameObject.FindGameObjectsWithTag("Target");
}
}
LookAtCamera
public class LookAtCamera : MonoBehaviour
{
// Values that will be set in the Inspector
public Transform target;
public float RotationSpeed;
private float timer = 0.0f;
public bool IsRotationFinished
{
get { return timer > 0.99f; }
}
// Update is called once per frame
void Update()
{
if (target != null && timer < 0.99f)
{
// Rotate us over time according to speed until we are in the required rotation
transform.rotation = Quaternion.Slerp(transform.rotation,
Quaternion.LookRotation((target.position - transform.position).normalized),
timer);
timer += Time.deltaTime * RotationSpeed;
}
}
}
Related
The first script (JumpFromMicrophone) I have created is a script where based on my MICROPHONE audio input, the game object (player) moves up on the Y axis. The game object also automatically moves forward using speed on the Z axis.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class JumpFromMicrophone : MonoBehaviour
{
public AudioSource source;
public AudioLoudnessDetection detector;
public Vector3 minPosition;
public Vector3 maxPosition;
public float speed = 2;
public float loudnessSensibility = 100;
public float threshold = 0.1f;
// The duration of the smooth transition
public float smoothTime = 0.1f;
private Vector3 velocity = Vector3.zero;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void FixedUpdate()
{
float loudness = detector.GetLoudnessFromMicrophone() * loudnessSensibility;
if (loudness < threshold)
loudness = 0;
else
loudness = (loudness - threshold) / (1 - threshold);
// Calculate the target position, keeping the current X and Z values
Vector3 targetPosition = Vector3.Lerp(minPosition, maxPosition, loudness);
targetPosition.x = transform.localPosition.x;
targetPosition.z = transform.localPosition.z;
// Smoothly move the object towards the target position
transform.localPosition = Vector3.SmoothDamp(transform.localPosition, targetPosition, ref velocity, smoothTime);
transform.Translate(Vector3.forward * speed * Time.deltaTime);
}
// reloads the scene if obstacle hits player
private void OnTriggerEnter(Collider other)
{
if (other.gameObject.tag == "Obstacle")
{
SceneManager.LoadScene("Game");
}
}
}
The second script (RNP) created records this audio picked up by the MICROPHONE and then plays it back to the player using a recording from a generated AudioSource. This is done using MaxRecordingTime, which I am fine using as I am going to relate it to timed game audio once this issue has been resolved.
public class RNP : MonoBehaviour
{
// The AudioClip that will be recorded
public AudioClip recordedClip;
// The maximum recording time in seconds
public int maxRecordingTime = 10;
void Start()
{
// Start the recording and playback coroutine
StartCoroutine(RecordAndPlayback());
}
IEnumerator RecordAndPlayback()
{
// Start recording from the default microphone
recordedClip = Microphone.Start(null, true, maxRecordingTime, 44100);
// Wait for the specified number of seconds
yield return new WaitForSeconds(maxRecordingTime);
// Stop the recording
Microphone.End(null);
// Create an AudioSource to play the recorded audio
AudioSource audioSource = gameObject.AddComponent<AudioSource>();
audioSource.clip = recordedClip;
audioSource.loop = false;
audioSource.Play();
// Wait for the audio to finish playing
yield return new WaitWhile(() => audioSource.isPlaying);
// Destroy the AudioSource
Destroy(audioSource);
}
}
However, the second script seems to clash with the first and implementing the second script does not allow for some aspects of the first script to work, I am beginning to think it might be something to do with the use of the Microphone for both scripts clashing, but I have no idea how to solve this issue so that both work together without disabling one another.
The JumpOnMicrophone script does not allow the player to move up the Y axis when the RNP script is added as a compenent onto the game object (player), but the player still moves along the Z axis.
Some fixes I have attemped that did not work:
Placing the 2nd script on another GameObject rather than the player
Combining both scripts
If anyone could help me figure this out, it would be greatly appreciated.
*** EDIT ***
AudioLoudnessDetection script
public class AudioLoudnessDetection : MonoBehaviour
{
public int sampleWindow = 64;
private AudioClip microphoneClip;
// Start is called before the first frame update
void Start()
{
MicrophoneToAudioClip();
}
// Update is called once per frame
void FixedUpdate()
{
}
public void MicrophoneToAudioClip()
{
string microphoneName = Microphone.devices[0];
microphoneClip = Microphone.Start(microphoneName, true, 20, AudioSettings.outputSampleRate);
}
public float GetLoudnessFromMicrophone()
{
return GetLoudnessFromAudioClip(Microphone.GetPosition(Microphone.devices[0]), microphoneClip);
}
public float GetLoudnessFromAudioClip(int clipPosition,AudioClip clip)
{
int startPosition = clipPosition - sampleWindow;
if (startPosition < 0)
return 0;
float[] waveData = new float[sampleWindow];
clip.GetData(waveData, startPosition);
// compute loudness
float totalLoudness = 0;
for (int i = 0; i < sampleWindow; i++)
{
totalLoudness += Mathf.Abs(waveData[i]);
}
return totalLoudness/ sampleWindow;
}
}
Hey Guys I've been having a problem lately that I cant seem to solve.
A sprite is supposed to roam around (as it does) while nothing is inside its radius, however if the player moves close to it the sprite should theoretically move towards it and stop roaming.
The sprite doesn't follow the player and cant even see its tag since I cant even see the contents of the "Collider2D[] hits".
using System.Collections.Generic;
using UnityEngine;
public class FireCultist : MonoBehaviour
{
public float moveTimeSeconds; //Time it will take object to move, in seconds.
private float xMax = 10.0f; // The boundaries of the spawn area
private float yMax = 10.0f;
private float xMin = -10.0f; // The boundaries of the spawn area
private float yMin = -10.0f;
public int xDistanceRange; // The max distance you can move at one time
public int yDistanceRange;
private BoxCollider2D boxCollider; //The BoxCollider2D component attached to this object.
private Rigidbody2D rb2D; //The Rigidbody2D component attached to this object.
private float inverseMoveTime; //Used to make movement more efficient.
public Vector2 start;
public Vector2 end;
public bool roam = true;
public Collider2D[] hits;
void Start()
{
boxCollider = GetComponent<BoxCollider2D>();
rb2D = GetComponent<Rigidbody2D>();
inverseMoveTime = 1f / moveTimeSeconds;
InvokeRepeating("RandomMove", 0.0f, 5.0f);
}
void Update()
{
Collider2D[] hits = Physics2D.OverlapCircleAll(transform.position, 10); // returns all colliders within radius of enemy
int i = 0;
while(hits.Length > i)
{
Debug.Log("Sees");
Debug.Log(hits[i]);
i++;
}
followPlayer();
if (roam)
{
Debug.Log("Roam");
transform.position = Vector2.MoveTowards(transform.position, end, inverseMoveTime * Time.deltaTime); //Random move to new position
}
}
public void followPlayer()
{
foreach (Collider2D hit in hits)
{
if (hit.tag == "Player") // if the player is within a radius
{
Debug.Log("Chasing Player");
transform.position = Vector2.MoveTowards(transform.position, GameObject.Find("Prefabs/Player").GetComponent<Transform>().position, inverseMoveTime * Time.deltaTime); // chase player
roam = false;
}
else
{
Debug.Log("Continues");
roam = true; // Continue RandomMove()
}
}
}
public void RandomMove() // gets random coordinates near enemy and moves there
{
float xDistance = Random.Range(-xDistanceRange, xDistanceRange); // check
float yDistance = Random.Range(-yDistanceRange, yDistanceRange);// check
if (xDistance < xMax && xDistance > xMin && yDistance < yMax && yDistance > yMin && roam == true) // If within boundaries of walking space
{
start = transform.position;
end = start + new Vector2(xDistance, yDistance);
Debug.Log("Roaming From : " + start + " To : " + end);
}
}
}
The roaming algorithm works however not too sure about the tag detection.
The script belongs to this enemy object
Player Object Properties
It looks like you are declaring a new hits variable during every update instead of using your class-level variable. This means the variable inside of followPlayer() will never be instantiated, and the information will not be passed between the two methods.
Try this:
void Update()
{
hits = Physics2D.OverlapCircleAll(transform.position, 10);
//...
}
You might also consider attaching a trigger collider to the enemy which sends a notification when the player enters/exits the trigger instead of relying on OverlapCircleAll()
void OnTriggerEnter2D(Collider2D col)
{
if(col.gameObject.tag == "Player"){
roam = false;
}
}
void OnTriggerExit2D(Collider2D col)
{
if(col.gameObject.tag == "Player"){
roam = true;
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Playables;
public class SpaceshipCutscene : MonoBehaviour
{
public Transform player;
public Transform[] npcs;
public Transform console;
public Camera FPSCamera;
public Camera mainCamera;
public Animator[] anim;
public float rotationSpeed = 3f;
public float distanceFromConsole;
private bool moveNpc = false;
private float sp = 0f;
private float distance;
// Use this for initialization
void Start()
{
}
private void Update()
{
distance = Vector3.Distance(transform.position, npcs[0].transform.position);
if (moveNpc)
{
// Soldier 2 rotating and looking at player
Vector3 dir = player.position - npcs[0].position;
dir.y = 0; // keep the direction strictly horizontal
Quaternion rot = Quaternion.LookRotation(dir);
// slerp to the desired rotation over time
npcs[0].rotation = Quaternion.Slerp(npcs[0].rotation, rot, rotationSpeed * Time.deltaTime);
var dist = Vector3.Distance(npcs[1].position, console.position);
if (dist < distanceFromConsole)
{
sp += Time.deltaTime;
sp = Mathf.Clamp(sp, 0f, 1f);
anim[1].SetFloat("WalkingSpeed", sp);
}
Vector3 dirToComputer = console.transform.position - npcs[1].position;
dirToComputer.y = 0;
Quaternion rot1 = Quaternion.LookRotation(dirToComputer);
npcs[1].rotation = Quaternion.Slerp(npcs[1].rotation, rot1, rotationSpeed * Time.deltaTime);
}
}
private void OnTriggerExit(Collider other)
{
if (HoriDoorManager.doorLockState == false && distance < 5f)
{
if (other.gameObject.tag == "SpaceshipCutscene")
{
FPSCamera.enabled = false;
mainCamera.enabled = true;
moveNpc = true;
anim[0].SetBool("Aiming", true);
anim[1].SetBool("Walktouse", true);
}
}
}
}
I'm calculating the distance between the player and the first npcs since I want the OnTriggerExit to trigger and work on specific direction.
When using a break point on the line:
FPSCamera.enabled = false;
It stop on this line and then I hit continue and it's getting inside the rest of the code in the Update.
But if I'm not adding a break point on that line it's not working it does nothing. Not giving errors or exception just not getting to the rest of the code in the Update.
https://docs.unity3d.com/ScriptReference/Collider.OnTriggerExit.html
OnTriggerExit occurs on the FixedUpdate after the Colliders have stopped touching
Update happens every frame, while FixedUpdate happens on a timer. So things here is probably just out of sync. Creating a break point will ensure that the frame stops and everything is probably aligned when you do that.
using System.Linq;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
public class Waypoints : MonoBehaviour
{
public GameObject[] waypoints;
public Transform target;
public float moveSpeed = 10f;
public float slowDownSpeed = 3f;
public float reverseSlowDownSpeed = 3f;
public float rotationSpeed = 1f;
private int targetsIndex = 0;
private Vector3 originalPosition;
private GameObject[] players;
public Transform reverseTarget;
private int reverseTargetsIndex = 0;
private Vector3 reverseOriginalPosition;
public bool random = false;
public bool getNextRandom = true;
// Use this for initialization
void Start()
{
waypoints = GameObject.FindGameObjectsWithTag("Blocks");
players = GameObject.FindGameObjectsWithTag("Player");
originalPosition = players[0].transform.localPosition;
}
// Update is called once per frame
void Update()
{
if (random == true)
{
RandomWayPointsAI();
}
else
{
WayPointsAI();
}
}
private void WayPointsAI()
{
if (targetsIndex == waypoints.Length)
targetsIndex = 0;
target = waypoints[targetsIndex].transform;
if (MovePlayer())
targetsIndex++;
}
private void ReverseWayPointsAI()
{
if (reverseTargetsIndex == 0)
reverseTargetsIndex = waypoints.Length - 1;
reverseTarget = waypoints[reverseTargetsIndex].transform;
if (MovePlayer())
reverseTargetsIndex--;
}
void RandomWayPointsAI()
{
if (random == true && getNextRandom)
{
int index = UnityEngine.Random.Range(0, waypoints.Length);
target = waypoints[index].transform;
getNextRandom = false;
}
getNextRandom = MovePlayer();
}
bool MovePlayer()
{
float distance = Vector3.Distance(players[0].transform.position, target.transform.position);
players[0].transform.localRotation = Quaternion.Slerp(players[0].transform.localRotation, Quaternion.LookRotation(target.position - players[0].transform.localPosition), rotationSpeed * Time.deltaTime);
//move towards the player
if (distance < 30)
{
players[0].transform.localPosition += players[0].transform.forward * slowDownSpeed * Time.deltaTime;
}
else
{
players[0].transform.localPosition += players[0].transform.forward * moveSpeed * Time.deltaTime;
}
if (distance < target.transform.localScale.magnitude)
return true;
else
return false;
}
void DrawLinesInScene()
{
// draw lines between each checkpoint //
for (int i = 0; i < waypoints.Length - 1; i++)
{
Debug.DrawLine(waypoints[i].transform.position, waypoints[i + 1].transform.position, Color.blue);
}
// draw a line between the original transform start position
// and the current transform position //
Debug.DrawLine(originalPosition, players[0].transform.position, Color.red);
Debug.DrawLine(reverseOriginalPosition, players[1].transform.position, Color.red);
// draw a line between current transform position and the next waypoint target
// each time reached a waypoint.
if (target != null)
Debug.DrawLine(target.transform.position, players[0].transform.position, Color.green);
if (reverseTarget != null)
Debug.DrawLine(reverseTarget.transform.position, players[1].transform.position, Color.green);
}
void AddColliderToWaypoints()
{
foreach (GameObject go in waypoints)
{
SphereCollider sc = go.AddComponent<SphereCollider>() as SphereCollider;
sc.isTrigger = true;
}
}
}
There are two problems with the script.
If the Move Speed is set to 3 i need to set the Rotation Speed at least to the 10 if i will set the Rotation Speed to 3 or 4 or 5 the rotation will be too wide and it will take much time to the player to get back on track after rotating.
But if it's 10 it seems he is almost rotating on the place so it's not good either.
I want to be able to change the player rotation speed but also to keep him on the waypoints track at any time. I mean that each waypoint the player is reaching to that he will get to it's center. In this case cubes so not only to touch the waypoint but to get to it's center then moving to the next waypoint.
Another problem i see is with the RandomWayPointsAI()
When i change it to use the random method i'm not sure if it's just picking up random positions around the grid or if it's picking random blocks(Cubes).
But it's never getting to a cube it' getting close or between two or sometimes on a cube and same as before also on the random i want to make the random waypoints not just positions but blocks and to get to each random block center.
Center i mean like standing on it.
A glaring problem in the showcased code is the use of local positions and rotations. When moving and rotating characters and objects in the world you should use world space.
Localposition and localrotation are based on the position and rotation of the parent object. Using those to move your object across the world will cause weird problems.
I think the following answer has a pretty accurate explanation of that stuff https://teamtreehouse.com/community/global-space-vs-local-space
This question already has answers here:
Rotate GameObject over time
(2 answers)
Closed 5 years ago.
in my project i have a bridge at the moment when i colide with the bridge it rotates and don't stop rotate, what i want is to rotate that bridge trough a specific point and stop rotate, that bridge is inside a gameobject that is my pivotPoint in general i rotate the pivotPoint not the bridge, so i did this:
using UnityEngine;
using System.Collections;
public class fallBridge : MonoBehaviour {
private Rigidbody ball;
public GameObject bridgePivot;
private bool colided;
private bool rotating = true;
// Update is called once per frame
void Start(){
colided = false;
}
void Update () {
if (colided) {
if (rotating) {
Vector3 to = new Vector3 (0, 0, -85);
if (Vector3.Distance (bridgePivot.transform.eulerAngles, to) > 0.01f) {
bridgePivot.transform.eulerAngles = Vector3.Lerp (bridgePivot.transform.rotation.eulerAngles, to, Time.deltaTime);
} else {
bridgePivot.transform.eulerAngles = to;
rotating = false;
}
}
}
}
void OnCollisionEnter(Collision other)
{
ball = GameObject.FindWithTag ("Player").GetComponent<Rigidbody> ();
if (other.gameObject.tag == "Player" && ball.transform.localScale == new Vector3(2.0f,2.0f,2.0f)) {
Debug.Log("ENTER");
colided = true;
}
}
}
what am i doing wrong?? the colision detection works perfectly but on the update method it never stops rotate :S
You should do this with coroutine. Call the coroutine function and pass in the GameOjbect to rotate and the angle to rotate to when OnCollisionEnter is called. You can read how this function work here.
Te example below will rotate the GameObject -85 degree in z-axis within 3 seconds.
You can change that to whatever suits you.
public class fallBridge : MonoBehaviour
{
private Rigidbody ball;
public GameObject bridgePivot;
bool rotating = false;
void OnCollisionEnter(Collision other)
{
ball = GameObject.FindWithTag("Player").GetComponent<Rigidbody>();
if (other.gameObject.CompareTag("Player") && ball.transform.localScale == new Vector3(2.0f, 2.0f, 2.0f))
{
Debug.Log("ENTER");
Vector3 rotationAngle = new Vector3(0, 0, -85);
StartCoroutine(RotateObject(bridgePivot, rotationAngle, 3f));
}
}
IEnumerator RotateObject(GameObject gameObjectToMove, Vector3 eulerAngles, float duration)
{
if (rotating)
{
yield break;
}
rotating = true;
Vector3 newRot = gameObjectToMove.transform.eulerAngles + eulerAngles;
Vector3 currentRot = gameObjectToMove.transform.eulerAngles;
float counter = 0;
while (counter < duration)
{
counter += Time.deltaTime;
gameObjectToMove.transform.eulerAngles = Vector3.Lerp(currentRot, newRot, counter / duration);
yield return null;
}
rotating = false;
}
The error is in this line:
bridgePivot.transform.eulerAngles = Vector3.Lerp (bridgePivot.transform.rotation.eulerAngles, to, Time.deltaTime);
When you use Lerp you typically have a fixed beginning and end, and you make the last parameter (t) go from 0 to 1. In your case the endpoint is fixed, the t parameters is fixed also and you vary your start. This means that each update you take a small step towards your goal, but this step is a percentage of the way. So each update you come closer, and your next step will be smaller.
What you should do is remember where you were when you started, and at what time you started. You also need to define a speed for your bridge. Then you can move the bridge from start to end and you get control over the speed.
public class fallBridge : MonoBehaviour {
private Rigidbody ball;
public GameObject bridgePivot;
public float rotateDuration = 2; // Time in seconds
// When you begin rotating you fill these three variables
private float startTime;
private Vector3 from;
private bool rotating = false;
// If the target doesn't change you might as well define it beforehand
private Vector3 to = new Vector3 (0, 0, -85);
void Update () {
if (rotating) {
float t = (Time.time - startTime) / rotateDuration;
if (t < 1) {
bridgePivot.transform.eulerAngles = Vector3.Lerp (from, to, t);
} else {
bridgePivot.transform.eulerAngles = to;
rotating = false;
}
}
}
void OnCollisionEnter(Collision other)
{
ball = GameObject.FindWithTag ("Player").GetComponent<Rigidbody> ();
if (other.gameObject.tag == "Player" && ball.transform.localScale == new Vector3(2.0f,2.0f,2.0f)) {
Debug.Log("ENTER");
startTime = Time.time; // Begin now
from = bridgePivot.transform.eulerAngles; // Remember the start position
rotating = true; // Signal to start rotating
}
}
}