Advertisement
Not a member of Pastebin yet?Sign Up, it unlocks many cool features!
- usingSystem.Collections;
- usingSystem.Collections.Generic;
- usingUnityEngine;
- usingUnityEngine.AI;
- publicclass BackAndForth : MonoBehaviour
- {
- [Header("Target Settings")]
- [Tooltip("The point to orbit around.")]
- public Transform _target;
- [Tooltip("The desired horizontal distance to maintain from the target.")]
- publicfloat _radius = 10.0f;
- [Tooltip("The desired height offset relative to the target's Y position.")]
- publicfloat _targetHeight = 5.0f;// Added height parameter
- [Header("Movement Settings")]
- [Tooltip("The constant forward speed of the entity.")]
- publicfloat _speed = 5.0f;
- [Tooltip("How quickly the entity can turn (degrees per second). Make this high enough!")]
- publicfloat _rotationSpeed = 180.0f;
- [Header("Steering Behavior")]
- [Tooltip("How far ahead (in seconds) to project position for steering. Tune this carefully.")]
- publicfloat _lookAheadTime = 0.5f;
- [Tooltip("How quickly the steering adjusts. Lower values = smoother but less responsive.")]
- [Range(1f, 20f)]
- publicfloat _steeringSmoothness = 5.0f;
- private Vector3 _currentSmoothedDirection;
- void Start()
- {
- if(_target ==null)
- {
- Debug.LogError("Orbit target is not assigned!", this);
- // Disable the script if the target isn't set, prevents errors in Update
- enabled =false;
- return;
- }
- // Initialize smoothed direction to current facing direction
- _currentSmoothedDirection = transform.forward;
- }
- void Update()
- {
- Vector3 targetBasePos = _target.position;// Cache target position for clarity
- // --- Steering Calculation ---
- // 1. Predict Future Position
- Vector3 futurePosition = transform.position+ transform.forward* _speed * _lookAheadTime;
- // 2. Calculate Vector from Target to Future Position
- Vector3 vectorToFuturePos = futurePosition - targetBasePos;
- // 3. Project onto Horizontal Plane (XZ) to find the horizontal direction component
- Vector3 horizontalVectorToFuture =new Vector3(vectorToFuturePos.x, 0f, vectorToFuturePos.z);
- // 4. Get Normalized Horizontal Direction
- // Handle the edge case where the future position is directly above or below the target
- Vector3 horizontalDirection;
- // Use sqrMagnitude for efficient zero-check (avoids square root)
- if(horizontalVectorToFuture.sqrMagnitude< 0.001f)
- {
- // If directly above/below, target point is ambiguous horizontally.
- // Choose a direction perpendicular to the entity's current UP direction, projected horizontally.
- // Or simply use the entity's current horizontal right as a fallback.
- Vector3 entityRightHorizontal =new Vector3(transform.right.x, 0f, transform.right.z).normalized;
- // Absolute fallback if entity happens to be pointing straight up/down
- if(entityRightHorizontal.sqrMagnitude< 0.001f)
- {
- entityRightHorizontal = Vector3.right;// Use world right if local right is vertical
- }
- horizontalDirection = entityRightHorizontal;
- }
- else
- {
- // Normalize the horizontal vector to get just the direction
- horizontalDirection = horizontalVectorToFuture.normalized;
- }
- // 5. Calculate the Final Target Orbit Point
- // Start with the horizontal position on the circle...
- Vector3 targetOrbitPoint = targetBasePos + horizontalDirection * _radius;
- // ...then set the desired vertical position.
- targetOrbitPoint.y= targetBasePos.y+ _targetHeight;
- // 6. Calculate *Raw* Desired Direction towards the height-adjusted orbit point
- Vector3 rawDesiredDirection =(targetOrbitPoint - transform.position).normalized;
- // Handle case where we are already AT the target point
- if(rawDesiredDirection == Vector3.zero)
- {
- rawDesiredDirection = transform.forward;// Maintain current direction
- }
- // --- Apply Smoothing ---
- // Smoothly interpolate the current steering direction towards the raw desired direction
- _currentSmoothedDirection = Vector3.Lerp(
- _currentSmoothedDirection,
- rawDesiredDirection,
- Time.deltaTime* _steeringSmoothness // Frame-rate independent smoothing
- );
- // Ensure the smoothed direction is normalized (Lerp might slightly change magnitude)
- if(_currentSmoothedDirection != Vector3.zero)
- {
- _currentSmoothedDirection.Normalize();
- }
- else
- {
- _currentSmoothedDirection = transform.forward;// Fallback if somehow zero
- }
- // --- Apply Rotation and Movement ---
- // 7. Rotate Towards the Smoothed Direction
- // This direction now implicitly guides towards the correct height AND horizontal orbit
- Quaternion targetRotation = Quaternion.LookRotation(_currentSmoothedDirection);
- transform.rotation= Quaternion.RotateTowards(transform.rotation, targetRotation, _rotationSpeed * Time.deltaTime);
- // 8. Move Forward along the entity's current facing direction
- transform.position+= transform.forward* _speed * Time.deltaTime;
- // --- Optional: Visualize (for debugging in Scene view) ---
- #if UNITY_EDITOR
- Debug.DrawLine(transform.position, futurePosition, Color.cyan);// Predicted future position
- // Draw the calculated target orbit point (the goal for steering)
- Debug.DrawLine(transform.position, targetOrbitPoint, Color.magenta);// Line from entity to target point
- Debug.DrawRay(targetOrbitPoint, Vector3.up* 0.5f, Color.magenta);// Mark target point location
- // Draw the raw and smoothed desired directions
- Debug.DrawLine(transform.position, transform.position+ rawDesiredDirection * 2.0f, Color.red);// Raw target dir
- Debug.DrawLine(transform.position, transform.position+ _currentSmoothedDirection * 2.5f, Color.green);// Smoothed target dir
- #endif
- }
- // Draw the target orbit circle in the Scene view for easy visualization
- void OnDrawGizmosSelected()
- {
- if(_target !=null)
- {
- #if UNITY_EDITOR // Ensure Handles call is only made in the editor
- // Calculate the center of the orbit circle at the target height
- Vector3 orbitCenter = _target.position;
- orbitCenter.y+= _targetHeight;// Adjust gizmo height
- UnityEditor.Handles.color= Color.cyan;
- // Draw the wire disc using the world UP axis
- UnityEditor.Handles.DrawWireDisc(orbitCenter, Vector3.up, _radius);
- #endif
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement