Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 14 Next capture
2021 2022 2023
2 captures
13 Jun 22 - 14 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
1
Question by VanessaMinehan · Nov 11, 2020 at 04:50 AM · 3dmovement scriptbeziercurvessnake

How to add Bezier Curves on a randomly moving object? 3d

I'm making a 3d dragon-snake that moves from point to point in the air, turning and facing the direction it goes, but it moves in straight lines and stops too long in one spot before going onto the next. I want to use Bezier curve or something similar that can make those movements smoother.

I'm not good at coding or math and have researched similar situations, they are all very different and I cant imagine how I could code something similar into what I'm already working with? I've spent too long trying to wrap my head around this, any ideas or suggestions appreciated.

thankyou :}

here's the movement script using System.Collections; using System.Collections.Generic; using UnityEngine;

 public class SerpentHeadMovement : MonoBehaviour
 {
     Vector3 destination;
     Vector3 originalPosition;
     //how far the dragon head can move from start
     public float maxDist = 5.0f; 
     //how far the dragon head can move in a single decision
     public float maxMovement = 2.0f;
     // Start is called before the first frame update
     public float distThreshold = 0.3f;
     public float speed = 1.0f;
     public float rotSpeed = 3.14f;
 
     
     void Start()
     {
         originalPosition = transform.position;
         NewDestination();
     }
 
     // Update is called once per frame
     void Update()
     {
         //have we reached destination?
         if (Vector3.Distance(transform.position, destination) < distThreshold)
         {
             //choose a new destination.
             NewDestination();
         }
         //move towards destination
         Vector3 subdestination = (destination - transform.position) * speed * Time.deltaTime;
         
         //save current rotation
         Quaternion rot = transform.rotation;
         transform.LookAt(transform.position + subdestination, Vector3.up );
         //save desired rot
         Quaternion destrot = transform.rotation;
         transform.rotation = Quaternion.Lerp(rot, destrot, Time.deltaTime * rotSpeed);
         transform.position += subdestination;
         
     }
 
     void NewDestination()
     {
         destination = transform.position + Random.insideUnitSphere * maxMovement;
         if (Vector3.Distance(destination, originalPosition) > maxDist)
         {
             destination = transform.position + Random.insideUnitSphere * maxMovement;    
         }
         
     }
     
 }
 

Also here is some other possible examples of related things that I found, but I've already got a headache looking at most of them. And most of them are really outdated idk if they will even help me.

https://answers.unity.com/questions/12689/moving-an-object-along-a-bezier-curve.html

https://stackoverflow.com/questions/56948496/how-to-make-game-objects-follow-a-path-in-order-in-unity-along-a-bezier-curve

https://answers.unity.com/questions/1700903/how-to-make-quadratic-bezier-curve-through-3-point.html

https://answers.unity.com/questions/1507662/how-to-make-multiple-evenly-spaced-objects-follow.html

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

1 Reply

· Add your reply
  • Sort: 
avatar image
0

Answer by jackmw94 · Nov 11, 2020 at 03:32 PM

I found this question really interesting! I haven't used Bezier curves before so got a bit too involved with the process. Below is a script to demonstrate them in action, it constructs a set of points along a curved bezier-ised line given the waypoint positions you pass it:

It looks long but it's half comments!

 using System.Collections.Generic;
 using System.Linq;
 using UnityEngine;
 
 public class BezierFun : MonoBehaviour
 {
     // Only setup required is populating these two fields:
     // Make a new gameobject and add a line renderer component. Give is a new material if you're feeling fancy
     // Make 3+ cubes and drag em all in
 
     [SerializeField] private LineRenderer _lineRenderer;
     [SerializeField] private Transform[] _targets;
 
     // Update just here to show GetWholePath in action
     private void Update()
     {
         if (_targets.Length < 3) return;
 
         Vector3[] points = GetWholePath(_targets);
 
         _lineRenderer.positionCount = points.Length;
         _lineRenderer.SetPositions(points.ToArray());
     }
 
     private static Vector3[] GetWholePath(Transform[] targets)
     {
         // this weird looking 'Select' argument is LINQ
         // it says for our collection of transforms, instead give me a collection of each of their positions
         // a nicer way for doing a big ol for loop getting each transforms' position
         return GetWholePath(targets.Select(p => p.position).ToArray());
     }
 
     // I think this function needs 3 or more positions to work, haven't tested with any less..
     private static Vector3[] GetWholePath(Vector3[] positions)
     {
         // We start by finding the points in between each of our positions
         // These intermediate points form the start and end of each bezier
         // We have to do this because otherwise the bezier lines don't match up nicely
         // Since the angle of lines in and out of the intermediate points is 180 degrees, we now know they will!
 
         List<Vector3> targetPoints = new List<Vector3>();
         for (var index = 0; index < positions.Length - 1; index++)
         {
             Vector3 firstPosition = positions[index];
             Vector3 secondPosition = positions[index + 1];
 
             Vector3 intermediate = firstPosition + (secondPosition - firstPosition) / 2f;
 
             targetPoints.Add(firstPosition);
             targetPoints.Add(intermediate);
         }
 
         // Last is more LINQ, just means 'positions[positions.Length - 1];'
         targetPoints.Add(positions.Last());
         
         // Now target points contains all the positions interleaved with the positions between them
         // [0] = Position 1
         // [1] = Point between 1 and 2
         // [2] = Position 2
         // [3] = Point between 2 and 3 ...
 
         int numBeziers = positions.Length - 2;
         List<Vector3> points = new List<Vector3>();
         
         // We can move straight towards the first intermediate point
         points.AddRange(GetPointsLinear(targetPoints[0], targetPoints[1]));
 
         for (int i = 1; i <= numBeziers; i++)
         {
             // Start index is the index of the intermediate point
             // Just converts an incrementing index to where the intermediate points sit in the targetPoints array
             // i=1 -> 1,  i=2 -> 3,  i=3 -> 5, etc..
             int startIndex = i * 2 - 1;
             
             // Bezier goes between two intermediate points with the actual position from the tranform as the control point
             points.AddRange(GetPointsBezier(targetPoints[startIndex], targetPoints[startIndex + 1], targetPoints[startIndex + 2]));
         }
         
         // Like with the first point, we can move straight to the last point
         points.AddRange(GetPointsLinear(targetPoints[targetPoints.Count - 2], targetPoints[targetPoints.Count - 1]));
 
         return points.ToArray();
     }
 
     private static Vector3[] GetPointsLinear(Vector3 pt1, Vector3 pt2, int lineDivisor = 10)
     {
         // just a flat line divided up. don't really need to do this tbh
         Vector3[] points = new Vector3[lineDivisor + 1];
         for (int i = 0; i < lineDivisor + 1; i++)
         {
             points[i] = Vector3.Lerp(pt1, pt2, i / (float) lineDivisor);
         }
 
         return points;
     }
 
     private static Vector3[] GetPointsBezier(Vector3 pt1, Vector3 pt2, Vector3 pt3, int lineDivisor = 10)
     {
         // LineDivisor essentially how many points we want
         // More points is more precision but if you have too many then this could mess with your 'reached destination' function
         Vector3[] points = new Vector3[lineDivisor + 1];
         for (int i = 0; i < lineDivisor + 1; i++)
         {
             // Line fraction goes from 0 to 1
             float lineFraction = i / (float) lineDivisor;
             
             // The Lerp function finds a point between two values at a given fraction
             // So if the fraction were 0, the result would be the first value
             // 0.5 is half way, 0.25 a quarter of the way
 
             // This is the main bezier logic:
             // We find a point along the line from 1 to 2
             Vector3 start = Vector3.Lerp(pt1, pt2, lineFraction);
             
             // We find a point along the line from 2 to 3
             Vector3 end = Vector3.Lerp(pt2, pt3, lineFraction);
             
             // We find a point along the line that connects the two previous points
             Vector3 linePoint = Vector3.Lerp(start, end, lineFraction);
             points[i] = linePoint;
         }
 
         return points;
     }
 }
Comment
Add comment · Show 4 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image VanessaMinehan · Nov 12, 2020 at 02:51 AM 0
Share

Thank you again, Jack! I feel like I'm actually starting to understand this now, you're explanations are really neat. I'll definitely try and fiddle around with this today and my project, I'll update if I'm successful. Thanks again

avatar image VanessaMinehan · Nov 12, 2020 at 08:13 AM 0
Share

Well, your code works, it draws a nice looking bezier curve between objects.

Even though its really neat I have no clue how to make it useful for my goals and project, I just cant understand how to use this to make objects follow beziers, and generate them or something. Idk Thanks anyway

avatar image jackmw94 VanessaMinehan · Nov 12, 2020 at 09:46 AM 0
Share

Ah you sounded so hopeful before D: $$anonymous$$y thinking was that at the start of your route you'd pass your waypoint positions into GetWholePath and that would give you waypoints along the curve, your dragon-snake could then follow these curve waypoints.

Don't feel like you should be using this though, this is just one way to achieve what you want to do. At the end of the day, if you're doing this for fun then put the fun first and if this is more frustrating than helpful then don't use it :)

Alternatively you could have it so the dragon-snake has a limit on how fast it can turn, it will always move forward in the direction its facing and will always try turn towards the next waypoint?

avatar image jackmw94 VanessaMinehan · Nov 16, 2020 at 04:39 PM 0
Share

Did you ever find a solution to this? I had a bad feeling that I took the fun of the problem solving away from this one and just gave you an awkward script to incorporate..

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

190 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

How can i make my character jump and slide on command? 0 Answers

how to make automatic gradual acceleration 1 Answer

My movement script is kind of broken for jumping (upward force is diminished after first jump) 1 Answer

sonic movement stick to the ground 1 Answer

How to make a top down character snap to different directions 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges