Search Unity

  1. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

soccer PlayerController and teamController

Discussion in 'Game Design' started by bobadi, Aug 31, 2023.

  1. bobadi

    bobadi

    Joined:
    Jan 3, 2019
    Posts:
    646
    intend to build up a soccer fieldplayer controller with moving, kicking abilities

    will have
    ballMX : ball mechanics. ball velocity, position, animplayer...
    playerCX : enums: state(hasball, idle) action(moving, trickin, waitin, kickin)

    the ball will have kinematic state while being possessed by player and at the end turns to rigidbody
    if it's trickin
    if its movin the ball is controlled by forces

    first synchronising player anim with ball anim
    focicsel1.gif

    focicsel2.gif
    there's no rotation, that should be controlled in script ballMX
    some q that's being calculated or recorded every lateupdate since start rotation.

    the ball position is recorded and being attacked by closest player
    tactic is decided by player's personality

    teamController:
    player positions and player actions
    by formation, ballholding team, and match phase

    thoughts? anybody has coded a group form control?
     
    Last edited: Aug 31, 2023
  2. bobadi

    bobadi

    Joined:
    Jan 3, 2019
    Posts:
    646
    now since ball animation is created at world (0,0,0)
    had to use a dummy object as parent to align ball animation with player position and rotation
    focicsel3.gif

    and doing a kick after this
    there's 1 meter foot-ball distance allowed
    focirug1.gif

    there's some velocity difference calculated while ball is kinematic
    sampling at every 0.2seconds, same settings
    focirug2.gif
     
    Last edited: Sep 1, 2023
  3. warthos3399

    warthos3399

    Joined:
    May 11, 2019
    Posts:
    1,691
    Pretty damn cool...:)
     
  4. bobadi

    bobadi

    Joined:
    Jan 3, 2019
    Posts:
    646
    thanks, it's still simple

    added ball tracking and kick force and direction by used kick
    focirug3.gif
     
  5. bobadi

    bobadi

    Joined:
    Jan 3, 2019
    Posts:
    646
    added left and right foot kick
    added lateupdate position lerp
    added kick pos calculation (yellow cube)

    next time I post the code if someone want to test
    focirug2LR.gif
    soccerCX is the player
    soccerCX.jpg
     
    Last edited: Sep 4, 2023
  6. bobadi

    bobadi

    Joined:
    Jan 3, 2019
    Posts:
    646
    here are soccer animations on turbosquid
    https://www.turbosquid.com/FullPreview/867443#
    https://www.turbosquid.com/FullPreview/1357220
    https://www.turbosquid.com/FullPreview/1295103#

    the 360 trick is mixamo's soccer spin if I remember correctly
    the ball anim for that spin trick
    https://www.mediafire.com/file/u3hxfy1855de4qm/spin.anim/file

    soccerCX
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class soccerCX : MonoBehaviour {
    6.  
    7.     public Animator animator;
    8.     public ballCX ballCX;
    9.  
    10.     public bool hasBall;
    11.     public enum ax {receivin, movin, dribblin, trickin, passin, kickin, waitin, goNext};
    12.     public ax action;
    13.  
    14.     [System.Serializable]
    15.     public class nt {
    16.         public float step;
    17.         public float kick;
    18.         public float end;
    19.     }
    20.     public nt NT = new nt();
    21.  
    22.     public Vector3 P;
    23.  
    24.     [System.Serializable]
    25.     public class BNS {
    26.  
    27.         public Transform rFoot;
    28.         public Transform lFoot;
    29.  
    30.         [System.Serializable]
    31.         public class P {
    32.             public Vector3 rFoot;
    33.             public Vector3 lFoot;
    34.         }
    35.         public P locP = new P();
    36.     }
    37.     public BNS bones = new BNS();
    38.  
    39.     public int footF;//foot forward 1:R -1:L
    40.  
    41.     [System.Serializable]
    42.     public class B {
    43.         //public float maxClosest = 5;//max distance to consider taking ball
    44.         public float maxStep = 2;//max distance to ball future position [to kick or taking]
    45.  
    46.         [Header("set by ball")]
    47.         public Vector3 locP;
    48.         public float dist;
    49.         public float angle;
    50.         [System.Serializable]
    51.         public class CLS {
    52.             public Vector3 P;
    53.             public Vector3 locP;
    54.             public float angle;
    55.             public float angleDif;//closestPoint - ball
    56.         }
    57.         public CLS closest = new CLS();
    58.  
    59.         public Vector3 kickP;//2 meteres average [maxStep]
    60.     }
    61.     public B ball = new B();
    62.  
    63.     [System.Serializable]
    64.     public class INS {
    65.  
    66.         public bool go4Ball;
    67.         public bool tackle;
    68.         //has ball
    69.         public bool kick;
    70.         public bool trick;
    71.         public bool attack;
    72.         //no ball
    73.         public bool go2Pos;
    74.         public bool move;
    75.     }
    76.     public INS ins = new INS();
    77.  
    78.     bool kickOffsetsSet;
    79.  
    80.     [System.Serializable]
    81.     public class ANM {
    82.  
    83.         [System.Serializable]
    84.         public class TRK {
    85.  
    86.             public int state;
    87.             public string ball;//anim
    88.             public float NTimeEnd = 0.85f;
    89.             public float force;
    90.         }
    91.         public TRK[] trick;
    92.  
    93.         public int trickN;
    94.  
    95.         [System.Serializable]
    96.         public class KCK {
    97.             public string name;
    98.             public Vector3 dir;//kick ball direction
    99.             public float force = 1;//multiply
    100.             public Vector3 offset;//[root pos at] kick - start
    101.             [Space(5)]
    102.             public float sec;//time to kick
    103.             public bool step;//if there is a step before kick
    104.  
    105.             [System.Serializable]
    106.             public class nt {
    107.                 public float step;//step endNT / kick startNT [for lerp]
    108.                 public float kick;
    109.                 public float end;
    110.             }
    111.             public nt NT = new nt();
    112.         }
    113.         public KCK[] kick;
    114.  
    115.         public int kickN;
    116.     }
    117.     public ANM anim = new ANM();
    118.  
    119.     AnimatorStateInfo animStateInfo;
    120.     public float NTime;
    121.     float NTimex;
    122.     public bool TRS;
    123.  
    124.     [System.Serializable]
    125.     public class DT {
    126.  
    127.         [System.Serializable]
    128.         public class TCK {
    129.             public float ballDist = 1f;
    130.         }
    131.         public TCK trick = new TCK();
    132.  
    133.         [System.Serializable]
    134.         public class KCK {
    135.             public float ballDist = 1f;
    136.             public Vector3 locKickP;//local pos of ball.kickP
    137.             public float dist2KickP;//meters for ball to reach ball.kickP
    138.             public float sec2KickP;//seconds for ball to reach ball.kickP [if moving]
    139.         }
    140.         public KCK kick = new KCK();
    141.     }
    142.     public DT data = new DT();
    143.  
    144.     public bool useLerp;
    145.  
    146.     [System.Serializable]
    147.     public class LRP {
    148.  
    149.         public float lerpT = 0.5f;
    150.         [Header("set by game")]
    151.         public bool isOn;
    152.         public Vector3 startP;
    153.         public Vector3 targetP;
    154.  
    155.         public float startT;
    156.         public float perc;
    157.     }
    158.     public LRP lerp = new LRP();
    159.  
    160.     public float timeNow;
    161.  
    162.     [System.Serializable]
    163.     public class DBG {
    164.  
    165.         public bool log;
    166.         public bool closest;
    167.         public Transform closestP;
    168.         public bool kick;
    169.         public Transform kickP;
    170.     }
    171.     public DBG doDebug = new DBG();
    172.  
    173.     int i;
    174.  
    175.     void Start () {
    176.         /*
    177.         if (!kickOffsetsSet) {
    178.             kickOffsetsSet = true;
    179.  
    180.             Vector3 startP = transform.position;
    181.             Quaternion startR = transform.rotation;
    182.  
    183.             for (i = 0; i < anim.kick.Length; i++) {
    184.  
    185.                 animator.Play ("KICK", 0, anim.kick[i].NT.kick);
    186.                 animator.Update(0);
    187.                 anim.kick [i].offset = transform.position - startP;
    188.                 transform.position = startP;
    189.                 transform.rotation = startR;
    190.             }
    191.         }
    192.         */
    193.     }
    194.  
    195.  
    196.     void Update () {
    197.  
    198.         timeNow = Time.time;
    199.         P = transform.position;
    200.  
    201.         ball.dist = (ballCX.transform.position - bones.rFoot.position).magnitude;
    202.         ball.locP = transform.InverseTransformPoint (ballCX.P.now);
    203.         ball.angle = Vector3.Angle(transform.forward, ballCX.P.now - P);
    204.  
    205.         ball.closest.P = ballCX.P.now + ballCX.P.futureDir * Vector3.Dot (P - ballCX.P.now, ballCX.P.futureDir);
    206.         ball.closest.locP = transform.InverseTransformPoint (ball.closest.P);
    207.         ball.closest.angle = Mathf.Atan2 (ball.closest.locP.x, ball.closest.locP.z) * Mathf.Rad2Deg;
    208.         ball.closest.angleDif = Mathf.Abs (ball.angle - ball.closest.angle);
    209.  
    210.         float distOnBallDir = ball.maxStep * Mathf.Sin (ball.closest.angleDif);
    211.         if (ball.locP.z > 0) distOnBallDir = Mathf.Abs (distOnBallDir);
    212.         else distOnBallDir = - Mathf.Abs (distOnBallDir);
    213.  
    214.         ball.kickP = ball.closest.P - ballCX.P.futureDir.normalized * distOnBallDir;
    215.          
    216.         data.kick.locKickP = transform.InverseTransformPoint (ball.kickP);
    217.         data.kick.dist2KickP = (ballCX.transform.position - ball.kickP).magnitude;
    218.         data.kick.sec2KickP = data.kick.dist2KickP / ballCX.velo;
    219.  
    220.         bones.locP.rFoot = transform.InverseTransformPoint (bones.rFoot.position);
    221.         bones.locP.lFoot = transform.InverseTransformPoint (bones.lFoot.position);
    222.  
    223.         if (bones.locP.rFoot.z > bones.locP.lFoot.z) footF = 1;
    224.         else footF = -1;
    225.  
    226.         hasBall = false;
    227.         if (action == ax.trickin) hasBall = true;
    228.         if (action == ax.dribblin) hasBall = true;
    229.         //if (action == ax.receivin) hasBall = true;
    230.         if (action == ax.passin) hasBall = true;
    231.  
    232.         animStateInfo = animator.GetCurrentAnimatorStateInfo (0);
    233.         NTimex = animStateInfo.normalizedTime;
    234.         NTime = NTimex % 1;
    235.  
    236.         TRS = animator.IsInTransition (0);
    237.  
    238.  
    239.         //ACTION END
    240.         if (!TRS && action == ax.trickin && NTimex > NT.end) {
    241.             action = ax.waitin;
    242.             if (doDebug.log) Debug.Log ("trick anim end");
    243.  
    244.             ballCX.transform.parent = null;
    245.             ballCX.setBallNoKinem (anim.trick [anim.trickN].force);
    246.  
    247.             animator.CrossFade ("MOVE", 0.2f);
    248.         }
    249.  
    250.         if (!TRS && action == ax.kickin && NTimex > NT.kick) {
    251.             //action = ax.waitin;
    252.             if (doDebug.log) Debug.Log ("kick anim end");
    253.  
    254.             ballCX.transform.parent = null;
    255.  
    256.             if (ball.dist < data.kick.ballDist) {
    257.                 if (doDebug.log) Debug.Log ("kickin");
    258.                 //ballCX.kickDir = transform.forward;
    259.                 ballCX.kickDir = transform.TransformDirection(anim.kick[anim.kickN].dir);
    260.                 ballCX.kickForce = anim.kick [anim.kickN].force;
    261.                 ballCX.kickBall ();
    262.             }
    263.  
    264.             if (NTimex > NT.end) {
    265.                 animator.CrossFade ("MOVE", 0.2f);
    266.  
    267.             }
    268.         }
    269.  
    270.  
    271.         //ACTION
    272.         if (ins.trick) {
    273.             ins.trick = false;
    274.  
    275.             action = ax.trickin;
    276.  
    277.             animator.CrossFade ("TRICK", 0.2f);
    278.             animator.SetFloat ("trick", anim.trickN);
    279.             NT.end = anim.trick[anim.trickN].NTimeEnd;
    280.  
    281.             ballCX.rootP.position = transform.position;
    282.             ballCX.rootP.rotation = transform.rotation;
    283.             ballCX.transform.parent = ballCX.rootP;
    284.  
    285.             if (doDebug.log) Debug.Log ("trick anim start");
    286.         }
    287.  
    288.         if (ins.kick) {
    289.  
    290.             if (hasBall) {
    291.                 ins.kick = false;
    292.                 action = ax.kickin;
    293.  
    294.                 animator.CrossFade ("KICK", 0.1f);
    295.                 animator.SetFloat ("kick", anim.kickN);
    296.                 NT.kick = anim.kick [anim.kickN].NT.kick;
    297.                 NT.end = anim.kick [anim.kickN].NT.end;
    298.  
    299.                 if (doDebug.log) Debug.Log ("kick anim start");
    300.             }
    301.  
    302.             if (!hasBall && ballCX.velo > 0.1f) {
    303.  
    304.                 if (data.kick.sec2KickP - anim.kick [anim.kickN].sec < 0.1f) {//the ball will reach position as kick animation will be kickin
    305.                     ins.kick = false;
    306.                     action = ax.kickin;
    307.  
    308.                     transform.rotation = Quaternion.LookRotation (ballCX.transform.position);//rotate towards ball
    309.  
    310.                     animator.CrossFade ("KICK", 0.1f);
    311.                     animator.SetFloat ("kick", anim.kickN);
    312.                     NT.kick = anim.kick [anim.kickN].NT.kick;
    313.                     NT.end = anim.kick [anim.kickN].NT.end;
    314.                     if (data.kick.locKickP.x > 0) animator.SetFloat ("kickfootF", 1);
    315.                     else animator.SetFloat ("kickfootF", -1);
    316.  
    317.                     if (useLerp) {
    318.                         lerp.isOn = true;
    319.                         lerp.startP = P;
    320.                         lerp.targetP = ball.kickP + (P - ball.kickP).normalized * 0.5f;
    321.                         lerp.startT = timeNow;
    322.                     }
    323.  
    324.                     if (doDebug.log) Debug.Log ("kick anim start");
    325.                 }
    326.             }
    327.         }
    328.  
    329.     }
    330.  
    331.  
    332.     void LateUpdate () {
    333.  
    334.         if (lerp.isOn) {
    335.             lerp.perc = (timeNow - lerp.startT) / lerp.lerpT;
    336.  
    337.             transform.position = Vector3.Lerp (lerp.startP, lerp.targetP, lerp.perc);
    338.  
    339.             if (lerp.perc > 0.99f) lerp.isOn = false;
    340.         }
    341.  
    342.  
    343.         if (doDebug.closest) {
    344.             doDebug.closestP.position = ball.closest.P;
    345.         }
    346.  
    347.         if (doDebug.kick) {
    348.             doDebug.kickP.position = ball.kickP;
    349.         }
    350.  
    351.     }
    352.  
    353. }
    ballCX
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class ballCX : MonoBehaviour {
    6.  
    7.     public Transform owner;
    8.     public soccerCX soccerCX;
    9.     public Transform rootP;//player pos at action start [dummy]
    10.     [Space(8)]
    11.     public Animator animator;
    12.     public Rigidbody rigidb;
    13.     public Vector3 veloDir;
    14.     public float velo;
    15.     public float forceCo = 100;
    16.     public Vector3 kickDir;
    17.     public float kickForce = 1;
    18.     [Space(8)]
    19.     public bool kinem;
    20.     public trajectx trajectx;
    21.  
    22.     [System.Serializable]
    23.     public class p {
    24.  
    25.         public float freq = 0.2f;//checkin pos
    26.         public Vector3 now;
    27.         public Vector3 last;
    28.  
    29.         public float startT;
    30.  
    31.         [System.Serializable]
    32.         public class F {
    33.             public Vector3 now;
    34.             public Vector3 future;
    35.             public float dist = 50;
    36.         }
    37.         public F future = new F();
    38.  
    39.         public Vector3 futureDir;
    40.     }
    41.     public p P = new p();
    42.  
    43.     public bool showFuturePos;
    44.  
    45.  
    46.     public float timeNow;
    47.  
    48.     void Start () {
    49.  
    50.         P.last = transform.position;
    51.         P.startT = Time.time;
    52.     }
    53.  
    54.     void Update () {
    55.      
    56.         timeNow = Time.time;
    57.         P.now = transform.position;
    58.  
    59.         if (timeNow - P.startT > P.freq) {
    60.             P.startT = timeNow;
    61.  
    62.             if (P.now != P.last) {
    63.                 veloDir = P.now - P.last;
    64.                 velo = veloDir.magnitude;
    65.  
    66.                 P.last = P.now;
    67.             }
    68.  
    69.         }
    70.  
    71.         if (owner != null) {
    72.  
    73.             if (soccerCX.action == soccerCX.ax.trickin) {
    74.  
    75.                 if (!kinem) {
    76.                     rigidb.isKinematic = true;
    77.                     kinem = true;
    78.  
    79.                     animator.enabled = true;
    80.                     animator.CrossFade (soccerCX.anim.trick [soccerCX.anim.trickN].ball, 0.2f);
    81.                 }
    82.  
    83.             }
    84.  
    85.         }
    86.  
    87.     }
    88.  
    89.     public void FixedUpdate(){
    90.  
    91.         if (showFuturePos) {
    92.  
    93.             P.future.now = P.now;
    94.             P.future.now.y = 0.5f;
    95.  
    96.             P.future.future = P.future.now + veloDir.normalized * P.future.dist;
    97.             P.future.future.y = 0.5f;
    98.              
    99.             Debug.DrawLine (P.future.now, P.future.future, Color.yellow);
    100.  
    101.             P.futureDir = (P.future.future - P.future.now).normalized;
    102.         }
    103.     }
    104.  
    105.  
    106.     public void setBallNoKinem(float forceCo0){
    107.  
    108.         animator.enabled = false;
    109.         rigidb.isKinematic = false;
    110.         kinem = false;
    111.         if (forceCo0 == 0) rigidb.AddForce (veloDir * forceCo * Time.deltaTime * 50);
    112.         else rigidb.AddForce (veloDir * forceCo0 * Time.deltaTime * 50);
    113.          
    114.         trajectx.getObj1 (transform.position, veloDir * forceCo);
    115.         trajectx.trackobj = true;
    116.  
    117.         print ("ballCX no kinem");
    118.     }
    119.  
    120.  
    121.     public void kickBall(){
    122.  
    123.         animator.enabled = false;
    124.         rigidb.isKinematic = false;
    125.         kinem = false;
    126.         rigidb.AddForce (kickDir * forceCo * kickForce * Time.deltaTime * 50);
    127.  
    128.         trajectx.getObj1 (transform.position, kickDir * forceCo * kickForce);
    129.         trajectx.trackobj = true;
    130.  
    131.         print ("ballCX kick");
    132.     }
    133.  
    134.     /*
    135.     void OnAnimatorMove(){
    136.  
    137.         //animation created at 0,0,0
    138.  
    139.         Vector3 currP = transform.position;
    140.  
    141.         transform.position = rootP.TransformPoint (currP);
    142.  
    143.     }
    144.     */
    145.  
    146. }
     
    Last edited: Sep 4, 2023
  7. bobadi

    bobadi

    Joined:
    Jan 3, 2019
    Posts:
    646
    the scene file
    https://www.mediafire.com/file/sl7gonvh3euhd4n/soccer_test.unity

    https://www.mediafire.com/file/hed4cfppdse1yhb/soccer.controller
    https://www.mediafire.com/file/np9ar4uk1myiccb/ball.controller


    the ball trajectory script. code by
    MIT License
    Copyright (c) 2019 Konstantinos Benos
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class trajectx : MonoBehaviour
    6. {
    7.  
    8.     public bool trackobj;
    9.     public Rigidbody rigidb;
    10.     public Vector3 pos;
    11.     public Vector3 lastpos;
    12.     public Vector3 velo;
    13.     public Vector3 velofwd;
    14.  
    15.     public int resolution = 30;
    16.  
    17.     private float velocity;
    18.     public LineRenderer lr;
    19.     private float angle = 0;
    20.     private float g;
    21.     private float rads;
    22.  
    23.     public Vector3[] arcPoints;
    24.  
    25.     void Start()
    26.     {
    27.         lr = this.GetComponent<LineRenderer>();
    28.         g = Mathf.Abs(Physics.gravity.y);
    29.     }
    30.  
    31.     void Update()
    32.     {
    33.         if(trackobj){
    34.          
    35.         //this.transform.position = gunpoint.position;
    36.         //this.transform.rotation = Quaternion.Euler(this.transform.rotation.eulerAngles.x, gunpoint.parent.rotation.eulerAngles.y, this.transform.rotation.eulerAngles.z);
    37.  
    38.             pos = rigidb.transform.position;
    39.             this.transform.position = lastpos;
    40.  
    41.             velo = pos - lastpos;
    42.             transform.LookAt(pos);
    43.  
    44.             //velocity = velo.magnitude;
    45.             velocity = rigidb.velocity.magnitude;
    46.  
    47.             RenderArc();
    48.  
    49.             lastpos = pos;
    50.         }
    51.     }
    52.  
    53.     public void getObj(Vector3 posx, Vector3 velox, Rigidbody rigidx){
    54.  
    55.         rigidb = rigidx;
    56.         velo = velox;
    57.         pos = posx;
    58.         lastpos = pos;
    59.  
    60.         trackobj = true;
    61.     }
    62.  
    63.     public void getObj1(Vector3 posx, Vector3 velox){
    64.  
    65.         velo = velox;
    66.         pos = posx;
    67.         lastpos = pos;
    68.  
    69.         trackobj = true;
    70.     }
    71.  
    72.     void RenderArc()
    73.     {
    74.         //angle = -gunpoint.parent.rotation.eulerAngles.x;
    75.  
    76.         lr.positionCount = resolution + 1;
    77.         lr.SetPositions(CalculateArcPoints());
    78.     }
    79.  
    80.  
    81.     Vector3[] CalculateArcPoints()
    82.     {
    83.         arcPoints = new Vector3[resolution + 1];
    84.  
    85.         rads = Mathf.Deg2Rad * angle;
    86.  
    87.         float maxDistance = ((velocity * Mathf.Cos(rads)) / g) * (velocity * Mathf.Sin(rads) + Mathf.Sqrt(Mathf.Pow(velocity * Mathf.Sin(rads), 2) + 2 * g * rigidb.transform.position.y));
    88.  
    89.         for(int i = 0; i <= resolution; i++)
    90.         {
    91.             float t = (float)i / (float)resolution;
    92.             arcPoints[i] = CalculatePoint(t, maxDistance);
    93.         }
    94.  
    95.         return arcPoints;
    96.     }
    97.  
    98.     Vector3 CalculatePoint(float t, float maxDist)
    99.     {
    100.         float x = t * maxDist;
    101.         float y = x * Mathf.Tan(rads) - ((g * x * x) / (2 * Mathf.Pow(velocity * Mathf.Cos(rads), 2)));
    102.         float z = 0f;
    103.  
    104.         return new Vector3(z, y, x);
    105.     }
    106.  
    107. }
    108.  
     
    Last edited: Sep 4, 2023
  8. bobadi

    bobadi

    Joined:
    Jan 3, 2019
    Posts:
    646
    will have to adapt for Renegade
    some features will need functions like
    -- foot farthest position (free dribbling)

    will use startRun anims for dribblin turns and ball receive / take

    this crossfade before lerp should be 0.02. used to crossfadeinfixedtime 0.2.
    326 animator.CrossFade ("KICK", 0.02f);

    the transition took too long, so lerp caused slidin
    0.02
    focirug5.gif

    look at ball
    focilook.gif
    here the distance is too big, should start with turn step [L90]

    and ball.maxclosest
    focimaxclose.gif
     
    Last edited: Sep 6, 2023
  9. bobadi

    bobadi

    Joined:
    Jan 3, 2019
    Posts:
    646
  10. bobadi

    bobadi

    Joined:
    Jan 3, 2019
    Posts:
    646
    some findings
    what makes hard to get good result

    - rootmotion rotation
    if animation starts with rotation offset, all crossfades mess up transform's orientation [run to kick, kick to run, kick to stand etc]
    (that's why most soccer games use straight and IP animations)

    this:
    focirug51.gif


    focirug52.gif
    vs.
    focirug53.gif

    - step and kick should be one anim
    using same transition values [in mecanim state-to-state] for one step anim to diff mocap kicks is not fluid
    (using different transition values for each might work though)

    - letting the ball to be physical if no input
    (I guess some games use fully kinematic ball)
     
    Last edited: Sep 9, 2023
  11. bobadi

    bobadi

    Joined:
    Jan 3, 2019
    Posts:
    646
    remade the kick animation so they start and end with step anim (and move approx. straight)
    remade the spin trick anim so it starts closer to player

    this is how it looks now
    foci01.gif
    demo
    GAMEPAD CONTROLLER NEEDED TO PLAY
    https://www.mediafire.com/file/3rhf0kfnhuc7rp3/SOCCER1.ZIP
    KICK: front right button1
    TRICK: front left button1
     
  12. bobadi

    bobadi

    Joined:
    Jan 3, 2019
    Posts:
    646
    hey, I managed to get kinda good soccer moves out of plask
    socceranm.gif
     
  13. bobadi

    bobadi

    Joined:
    Jan 3, 2019
    Posts:
    646
    the ball - time to target
    soccerballtargetforce.gif
     
  14. nikkinik778

    nikkinik778

    Joined:
    Mar 20, 2021
    Posts:
    1
    much appreciated for sharing such wonderful resource
     
  15. bobadi

    bobadi

    Joined:
    Jan 3, 2019
    Posts:
    646
    what I'll manage to come up with, will be added to the Renegade asset

    +soccer mocap animations
    https://www.mocapfiles.com/soccer.html

    here's a kick without offset and with offset
    the receiver is moved by ball targetP
    kicknoffset.gif
     
  16. bobadi

    bobadi

    Joined:
    Jan 3, 2019
    Posts:
    646
    scissor kick
    kicknscissor.gif
     
  17. bobadi

    bobadi

    Joined:
    Jan 3, 2019
    Posts:
    646
    rainbow flick
    this needed separate normtime for ball set rigidbody
    and settable ball direction instead of default ball direction calculated in update
    rainboflik.gif
     
  18. bobadi

    bobadi

    Joined:
    Jan 3, 2019
    Posts:
    646
    volley kick and scissor kick
    decided by the pass kick [diff targetP] which is modifiable after kick anim started
    scissnvolleykick.gif
     
  19. bobadi

    bobadi

    Joined:
    Jan 3, 2019
    Posts:
    646
    added passing to moving player
    kickpassmovin.gif
     
  20. bobadi

    bobadi

    Joined:
    Jan 3, 2019
    Posts:
    646
    added new action cut (there's stand, move, trick, kick etc action)
    for one-touch
    here the ball doesn't have to be animated
    cut.gif
    the first one is unfinished
    have to take into account where the cut anim ends
    had to add a turn state from stand for second one
    FturnR180.gif

    also now it's possible to do this
    tricknkick.gif
     
  21. bobadi

    bobadi

    Joined:
    Jan 3, 2019
    Posts:
    646
    lerping to ball before kick
    rotateto0.jpg
    default (no lerping)
    lerpP000.gif

    position lerp (offset: 0.3,0,0)
    lerpP100.gif
    rotation lerp (offsetR: 0.2,0,0)
    lerpP010.gif

    updated: separated position lerp and rotation lerp
     
    Last edited: Nov 2, 2023
  22. bobadi

    bobadi

    Joined:
    Jan 3, 2019
    Posts:
    646
    rotating towards ball after kick
    [RTo]
    rotateto1.jpg

    same animation, different outDir for ball (-0.5,0,-1 and 0.2,0,-1) + outAnm turn180
    lerpTRo.gif
     
  23. bobadi

    bobadi

    Joined:
    Jan 3, 2019
    Posts:
    646
    foot side: inside / outside

    data.goal.shoot.use [within a set distance]
    kicking foot is being choosed based on goalAngle and footside

    footside.gif

    default kick (no data.goal.shoot.use)
    footside0.gif
     
    Last edited: Nov 2, 2023
  24. bobadi

    bobadi

    Joined:
    Jan 3, 2019
    Posts:
    646
    data.trick.instantBallAnm : [false]

    to avoid teleporting ball
    - not start the ball animation instantly
    there's also lerpP implemented for trick

    true / false
    instantball.gif
     
  25. bobadi

    bobadi

    Joined:
    Jan 3, 2019
    Posts:
    646
    trickL + trickR
    the ball is not animated for these

    added moveF selectable after trick [+timeOut for runStop]
    trickLNtrickR.gif
     
  26. bobadi

    bobadi

    Joined:
    Jan 3, 2019
    Posts:
    646
    looks like this simple code will work for kinematic ball rotation
    kinemBallR.gif
    Code (CSharp):
    1.     public Transform ball;
    2.     public float speed = 500;
    3.  
    4.     public Vector3 move;
    5.     public Vector3 P;
    6.     public Vector3 lastP;
    7.  
    8.     void Update () {
    9.         P = ball.position;
    10.     }
    11.  
    12.  
    13.     void LateUpdate () {
    14.         move = P - lastP;
    15.         ball.RotateAround (ball.position, Vector3.Cross (Vector3.up, move), speed * Time.deltaTime);
    16.         lastP = P;
    17.     }
     
  27. bobadi

    bobadi

    Joined:
    Jan 3, 2019
    Posts:
    646
    how to create animation for ball:

    1. ball animation panel: create new clip
    - we just need position, so Add Property: Transform > Position
    - set length to clip length (0.867x60 = 52)
    - set to default in animator
    socceranim1.jpg
    2. player animator: add clip and set to default
    - set true: looping and all bake into pose*
    socceranim2.jpg
    3. animate ball position
    - set timeScale to slow (0.1)
    - select ball in hierarchy and the new clip in animation
    - while playing, stop play and move the ball where you want it in scene view
    socceranim3.jpg


    socceranim1.gif
    it's pretty trial-and-error, because it seems the animation panel doesn't show progression while runtime


    *in-game, with controller these should be set to false
     
    Last edited: Nov 13, 2023
  28. bobadi

    bobadi

    Joined:
    Jan 3, 2019
    Posts:
    646
    one thing I overlooked
    ball.anmOffset : the ball local position at the start of the animation

    added possibility to use physics for two-touch trick
    [ball.contact]

    force + force ................................. anm + force
    anm2trickR.gif anmAtrickR.gif


    force + force ................................. anm + force
    anm2trickF.gif anmAtrickF.gif

    soccatrickF1.jpg
     
  29. austinbyamugisha

    austinbyamugisha

    Joined:
    Aug 10, 2022
    Posts:
    4
    Bro this is amazing! Do you have any character controller script for the player?
     
  30. bobadi

    bobadi

    Joined:
    Jan 3, 2019
    Posts:
    646
    hey, thanks.

    it is a character controller script and it's included in Renegade now as a preview (work-in-progress)
     
  31. austinbyamugisha

    austinbyamugisha

    Joined:
    Aug 10, 2022
    Posts:
    4
    Wow! Do you have a link to it, cause your work is really top notch. Keep up the grind!
     
  32. austinbyamugisha

    austinbyamugisha

    Joined:
    Aug 10, 2022
    Posts:
    4
    I mean a free link cause I'm broke lol.
     
  33. austinbyamugisha

    austinbyamugisha

    Joined:
    Aug 10, 2022
    Posts:
    4
    Oh and one more thing, could you please update your scene for unity?
    Cuz unfortunately it ain't working.
    Thanks.