Beispiel #1
0
    void SwitchCamera(Transform t)
    {
        if (onLock && t)
        {
            if (t != player)
            {
                lockIcon.gameObject.SetActive(true);
                PositionConstraint pc = lockIcon.GetComponent <PositionConstraint>();
                if (pc)
                {
                    if (pc.sourceCount > 0)
                    {
                        pc.RemoveSource(0);
                    }
                    constraintSource.sourceTransform = t;
                    constraintSource.weight          = 1;
                    pc.AddSource(constraintSource);
                    //pc.translationOffset = Vector3.zero;
                    //pc.translationAtRest = Vector3.zero;
                }
                lockVcam.GetComponent <CinemachineVirtualCamera>().LookAt   = t;
                lockVcam.GetComponent <CinemachineVirtualCamera>().Priority = mainPriority + 1;
                return;
            }
        }

        lockIcon.gameObject.SetActive(false);
        lockVcam.GetComponent <CinemachineVirtualCamera>().Priority = mainPriority - 1;
    }
Beispiel #2
0
    //Add Sourcer
    public static void AddTransform(this PositionConstraint posCons, Transform source, float weight = 1)
    {
        ConstraintSource constraint = new ConstraintSource();

        constraint.sourceTransform = source;
        constraint.weight          = weight;

        posCons.AddSource(constraint);
    }
Beispiel #3
0
        protected virtual void CreateFootPrints()
        {
            _footprints = Instantiate <GameObject>(Resources.Load <GameObject>("Footprints/Footprints")).GetOrCreateComponent <PositionConstraint>();
            _footprints.transform.ResetTransformation();
            ConstraintSource source = new ConstraintSource();

            source.sourceTransform = transform;
            source.weight          = 1.0f;
            _footprints.AddSource(source);
            _footprints.constraintActive = true;
        }
Beispiel #4
0
    /*        end          */

    // 追従する親をセット
    public void SetConstraintTransform(Transform parent)
    {
        // 対象のオブジェクトに追従する
        MyConstraintSource.sourceTransform = parent;
        MyConstraintSource.weight          = 1.0f;

        MyPositionConstraint.AddSource(MyConstraintSource);
        MyPositionConstraint.translationOffset = Vector3.zero;
        MyPositionConstraint.enabled           = true;
        MyPositionConstraint.constraintActive  = true;
    }
Beispiel #5
0
    public override void OnStateExit(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
    {
        ConstraintSource cameraSource = new ConstraintSource {
            sourceTransform = cameraControl.targetFocus.transform,
            weight          = 1
        };

        positionConstraint.translationOffset = cameraControl.transform.position - cameraControl.targetFocus.transform.position;
        positionConstraint.AddSource(cameraSource);
        positionConstraint.constraintActive = true;
        positionConstraint.locked           = true;
    }
Beispiel #6
0
        private void SetCameraConstraint(SimplePhysicsMovement coreInstance)
        {
            var sourceCount = _cameraConstraint.sourceCount;

            for (int i = 0; i < sourceCount; i++)
            {
                _cameraConstraint.RemoveSource(0);
            }
            ConstraintSource coreSource = new ConstraintSource();

            coreSource.sourceTransform = coreInstance.transform;
            coreSource.weight          = 1;
            _cameraConstraint.AddSource(coreSource);
        }
Beispiel #7
0
    public void AttachModel(GameObject _model)
    {
        model = _model;

        var source = new ConstraintSource
        {
            sourceTransform = model.transform,
            weight          = 1
        };

        Debug.Log($"{name}: Attaching {_model.name}", this);

        constraint.AddSource(source);
    }
Beispiel #8
0
    private static void BuildView(string name, Vector3 position, Vector3 direction, Transform reference, PositionConstraint constraint, int index, float weight = 0)
    {
        Smart3DOFTarget view = new GameObject(name + " Target").AddComponent <Smart3DOFTarget>();

        view.reference          = reference;
        view.positionConstraint = constraint;
        view.transform.position = position;
        //view.transform.position = Vector3.zero;
        view.transform.forward = direction;
        view.index             = index;
        ConstraintSource source = new ConstraintSource();

        source.sourceTransform = view.transform;
        source.weight          = weight;
        constraint.AddSource(source);
    }
Beispiel #9
0
        private static void LockPosition(PlayerMovement player, Transform carryPoint)
        {
            Vector3 carryPosition = carryPoint.position;

            carryPoint.position = new Vector3(
                carryPosition.x,
                player.transform.position.y,
                carryPosition.z
                );

            PositionConstraint parent = player.gameObject.AddComponent <PositionConstraint>();

            parent.AddSource(new ConstraintSource {
                sourceTransform = carryPoint, weight = 1
            });
            parent.constraintActive = true;
        }
Beispiel #10
0
    protected override bool Open(T unit)
    {
        var result = base.Open(unit);

        if (result)
        {
            transform.position = mainCamera.WorldToScreenPoint(unit.transform.position + WorldOffset)
                                 .SetZ(transform.parent != null ? transform.parent.position.z : 0) + ScreenOffset;

            if (constraint)
            {
                while (constraint.sourceCount > 0)
                {
                    constraint.RemoveSource(0);
                }

                constraint.translationOffset = WorldOffset;
                constraint.AddSource(new ConstraintSource
                {
                    sourceTransform = unit.transform,
                    weight          = 1
                });
                constraint.enabled = true;
            }

            if (follower)
            {
                follower.offset       = WorldOffset;
                follower.screenOffset = ScreenOffset;
                follower.target       = unit.transform;
                follower.enabled      = true;
            }
        }

        return(result);
    }
        void Start()
        {
            for (int i = 0; i < 32; i++)
            {
                if (LayerMask.LayerToName(i) == "Liquid")
                {
                    layer = i;
                    break;
                }
            }

            anchor = new GameObject(transform.parent.name + "_slosher " + count)
            {
                layer = layer,
            };
            anchor.transform.position = transform.position;

            Rigidbody anchorBody = anchor.AddComponent <Rigidbody>();

            anchorBody.mass        = 1f;
            anchorBody.isKinematic = true;
            anchorBody.useGravity  = false;

            ConfigurableJoint joint = anchor.AddComponent <ConfigurableJoint>();

            joint.anchor = Vector3.zero;
            joint.axis   = Vector3.right;
            joint.autoConfigureConnectedAnchor = false;
            joint.connectedAnchor = new Vector3(0f, pendulumLength, 0f);
            joint.secondaryAxis   = Vector3.up;
            joint.xMotion         = ConfigurableJointMotion.Locked;
            joint.yMotion         = ConfigurableJointMotion.Locked;
            joint.zMotion         = ConfigurableJointMotion.Locked;
            joint.angularXMotion  = ConfigurableJointMotion.Limited;
            joint.angularYMotion  = ConfigurableJointMotion.Locked;
            joint.angularZMotion  = ConfigurableJointMotion.Limited;
            SoftJointLimit sjl = joint.lowAngularXLimit;

            sjl.limit              = -liquidAngularLimit;
            sjl.bounciness         = liquidBounciness;
            joint.lowAngularXLimit = sjl;

            sjl                     = joint.highAngularXLimit;
            sjl.limit               = liquidAngularLimit;
            sjl.bounciness          = liquidBounciness;
            joint.highAngularXLimit = sjl;

            sjl                 = joint.angularZLimit;
            sjl.limit           = liquidAngularLimit;
            sjl.bounciness      = liquidBounciness;
            joint.angularZLimit = sjl;

            PositionConstraint constraint = anchor.AddComponent <PositionConstraint>();
            ConstraintSource   source     = new ConstraintSource()
            {
                weight          = 1f,
                sourceTransform = transform
            };

            constraint.AddSource(source);
            constraint.locked           = true;
            constraint.constraintActive = true;

            pendulum = new GameObject(transform.parent.name + "_slosher_pendulum " + count)
            {
                layer = layer
            };
            pendulum.transform.position = transform.position - Vector3.down * pendulumLength;

            Rigidbody pendulumBody = pendulum.AddComponent <Rigidbody>();

            pendulumBody.mass       = pendulumMass;
            pendulumBody.drag       = pendulumDrag;
            pendulumBody.useGravity = true;

            SphereCollider collider = pendulum.AddComponent <SphereCollider>();

            collider.radius = 0.01f;

            joint.connectedBody = pendulumBody;

            count++;
        }
Beispiel #12
0
        public void StartMatch()
        {
            // TextAsset gameJson = Resources.Load(filePath) as TextAsset;
            // Debug.Log(gameJson);
            // game = JsonUtility.FromJson<SlippiGame>(gameJson.text);
            //Debug.Log(game.settings.stageId);
            foreach (Transform child in world.transform)
            {
                GameObject.Destroy(child.gameObject);
            }
            if (game == null)
            {
                Debug.LogWarning("You need to set a game in order to play it back");
            }
            player1Index = game.settings.players[0].playerIndex;
            player2Index = game.settings.players[1].playerIndex;

            string stageName = SlippiLookupTable.GetStageName(game.settings.stageId);
            string p1Name    = SlippiLookupTable.GetCharacterName(game.settings.players[0].characterId);
            string p2Name    = SlippiLookupTable.GetCharacterName(game.settings.players[1].characterId);

            Debug.Log(stageName);
            Debug.Log(p1Name);
            Debug.Log(p2Name);

            // Load Stage
            UnityEngine.Object stagePrefab = Resources.Load("StagePrefabs/" + stageName + "/" + stageName);
            GameObject         stage       = Instantiate(stagePrefab) as GameObject;

            stage.transform.parent        = world;
            world.transform.position      = new Vector3(0, -1, 7);
            stage.transform.localPosition = new Vector3(0, 0, 0);
            stage.transform.eulerAngles   = new Vector3(0, 180, 0);
            // Load Characters

            UnityEngine.Object p1Prefab = Resources.Load("CharacterPrefabs/" + p1Name + "/" + p1Name);
            GameObject         p1;

            if (p1Prefab == null)
            {
                p1 = GameObject.CreatePrimitive(PrimitiveType.Sphere);
            }
            else
            {
                p1 = Instantiate(p1Prefab) as GameObject;
            }
            Animation _1Animation = p1.AddComponent(typeof(Animation)) as Animation;

            p1Animation = _1Animation;
            GameObject p1G = new GameObject();

            player1 = p1G.transform;
            GameObject p2G = new GameObject();

            player2                    = p2G.transform;
            player1.parent             = world;
            player2.parent             = world;
            p1.transform.parent        = player1;
            p1.transform.localPosition = new Vector3(0, 0, 0);
            p1.transform.localScale    = new Vector3(100, 100, 100);

            // Apply Red Material to P1
            Material p1Material = Resources.Load("Materials/Player1Material") as Material;

            foreach (Transform child in p1.transform)
            {
                SkinnedMeshRenderer meshRenderer = child.GetComponent <SkinnedMeshRenderer>();
                if (meshRenderer == null)
                {
                    continue;
                }
                meshRenderer.sharedMaterial = p1Material;
            }


            UnityEngine.Object p2Prefab = Resources.Load("CharacterPrefabs/" + p2Name + "/" + p2Name);

            GameObject p2;

            if (p2Prefab == null)
            {
                p2 = GameObject.CreatePrimitive(PrimitiveType.Sphere);
            }
            else
            {
                p2 = Instantiate(p2Prefab) as GameObject;
            }

            Animation _2Animation = p2.AddComponent(typeof(Animation)) as Animation;

            p2Animation = _2Animation;

            p2.transform.parent        = player2;
            p2.transform.localPosition = new Vector3(0, 0, 0);
            p2.transform.localScale    = new Vector3(100, 100, 100);

            // Apply Blue Material to P2
            Material p2Material = Resources.Load("Materials/Player2Material") as Material;

            foreach (Transform child in p2.transform)
            {
                SkinnedMeshRenderer meshRenderer = child.GetComponent <SkinnedMeshRenderer>();
                if (meshRenderer == null)
                {
                    continue;
                }
                meshRenderer.sharedMaterial = p2Material;
            }

            // ================= Initiate Shield Stuff
            UnityEngine.Object shieldPrefab = Resources.Load("CharacterPrefabs/" + p2Name + "/" + p2Name);

            player1Shield = GameObject.CreatePrimitive(PrimitiveType.Sphere);
            player2Shield = GameObject.CreatePrimitive(PrimitiveType.Sphere);
            Material p1ShieldMaterial = Resources.Load("Materials/Player1ShieldMaterial") as Material;
            Material p2ShieldMaterial = Resources.Load("Materials/Player2ShieldMaterial") as Material;

            player1Shield.GetComponent <MeshRenderer>().material = p1ShieldMaterial;
            player2Shield.GetComponent <MeshRenderer>().material = p2ShieldMaterial;

            player1Shield.transform.parent        = p1.transform;
            player2Shield.transform.parent        = p2.transform;
            player1Shield.name                    = "Shield";
            player2Shield.name                    = "Shield";
            player1Shield.transform.localPosition = new Vector3(0, .07f, 0);
            player2Shield.transform.localPosition = new Vector3(0, .07f, 0);
            player1Shield.transform.localScale    = new Vector3(.12f, .12f, .12f);
            player2Shield.transform.localScale    = new Vector3(.12f, .12f, .12f);
            player1Shield.SetActive(false);
            player2Shield.SetActive(false);

            // ================ End Shield Stuff

            DirectoryInfo p1Dir = new DirectoryInfo("Assets/Resources/CharacterPrefabs/" + p1Name + "/Animation/");

            FileInfo[] p1files = p1Dir.GetFiles("*.fbx");


            foreach (FileInfo f in p1files)
            {
                string        animationName = Path.GetFileNameWithoutExtension(f.ToString());
                AnimationClip clip          = Resources.Load <AnimationClip>("CharacterPrefabs/" + p1Name + "/Animation/" + animationName);
                clip.legacy = true;
                p1Animation.AddClip(clip, animationName);
            }


            // Prepare Animations
            DirectoryInfo p2Dir = new DirectoryInfo("Assets/Resources/CharacterPrefabs/" + p2Name + "/Animation/");

            FileInfo[] p2files = p2Dir.GetFiles("*.fbx");


            foreach (FileInfo f in p2files)
            {
                string        animationName = Path.GetFileNameWithoutExtension(f.ToString());
                AnimationClip clip          = Resources.Load <AnimationClip>("CharacterPrefabs/" + p2Name + "/Animation/" + animationName);
                clip.legacy = true;
                p2Animation.AddClip(clip, animationName);
            }


            // Lock Animations for offending objects that change entire model location
            foreach (Transform child in p1.transform.GetComponentsInChildren <Transform>())
            {
                if (child.name == "JOBJ_1")
                {
                    PositionConstraint pc = child.gameObject.AddComponent(typeof(PositionConstraint)) as PositionConstraint;
                    ConstraintSource   constraintSource = new ConstraintSource();
                    constraintSource.sourceTransform = child.parent;
                    pc.AddSource(constraintSource);
                    pc.constraintActive = true;
                }
                if (child.name == "JOBJ_2")
                {
                    p1RotationToReset = child;
                }
            }
            ;
            foreach (Transform child in p2.transform.GetComponentsInChildren <Transform>())
            {
                if (child.name == "JOBJ_1")
                {
                    PositionConstraint pc = child.gameObject.AddComponent(typeof(PositionConstraint)) as PositionConstraint;
                    ConstraintSource   constraintSource = new ConstraintSource();
                    constraintSource.sourceTransform = child.parent;
                    pc.AddSource(constraintSource);
                    pc.constraintActive = true;
                }
                if (child.name == "JOBJ_2")
                {
                    p2RotationToReset = child;
                }
            }
            ;


            SlippiPost post1 = game.frames[0].players[player1Index].post;

            stockHolder = new GameObject("Stocks");
            stockHolder.transform.parent = world.transform;

            player1Stocks = new List <GameObject>();
            player2Stocks = new List <GameObject>();
            InstantiateStocks(post1.stocksRemaining, 1, p1Material, player1Stocks);
            InstantiateStocks(post1.stocksRemaining, 2, p2Material, player2Stocks);
            stockHolder.transform.localScale    = new Vector3(5, 5, 2);
            stockHolder.transform.localPosition = new Vector3(0, 0, -28);
            player1Stock = post1.stocksRemaining;
            player2Stock = post1.stocksRemaining;


            world.localScale = new Vector3(1 * worldScale, 1 * worldScale, 1 * worldScale);
            matchStarted     = true;

            // Tell Hypersdk players to reload
            hsdkc = GetComponent <HyperSDKController>();
            sceneID++;
            hsdkc.sceneID = sceneID;
        }
Beispiel #13
0
        public void FixSpecialPoints()
        {
            if (!source)
            {
                source = GetComponent <HandSearchEngine>();
            }

            Transform wrist    = hand.wristPoint.original;
            Transform index1   = hand.index1Point.original;
            Transform middle1  = hand.middle1Point.original;
            Transform ring1    = hand.middle1Point.original;
            Transform pinky1   = hand.pinky1Point.original;
            Transform thumb1   = hand.thumb1Point.original;
            Transform indexTip = hand.indexTipPoint.original;
            Transform thumbTip = hand.thumbTipPoint.original;

            Vector3 wristToRing1  = ring1.position - wrist.position;
            Vector3 wristToIndex1 = index1.position - wrist.position;

            Vector3 worldPalmNormalDir;

            if (side == Side.Left)
            {
                worldPalmNormalDir = Vector3.Cross(wristToIndex1, wristToRing1);
            }
            else
            {
                worldPalmNormalDir = Vector3.Cross(wristToRing1, wristToIndex1);
            }

            Vector3 frontFingerCenter  = (index1.position + middle1.position + ring1.position + pinky1.position) / 4.0f;
            Vector3 worldPalmCenterPos = (wrist.position * centerRange + frontFingerCenter * (1.0f - centerRange));

            Vector3 centerToWristDir             = wrist.position - worldPalmCenterPos;
            Vector3 frontFingerCenterToIndex1Dir = index1.position - frontFingerCenter;

            Vector3 frontFingerCenterToIndex = index1.position - frontFingerCenter;

            if (!specialPoints.palmCenterPoint.original)
            {
                specialPoints.palmCenterPoint.original          = BasicHelpers.InstantiateEmptyChild(wrist.gameObject, "PalmCenter." + side.ToString()).transform;
                specialPoints.palmCenterPoint.original.position = worldPalmCenterPos + (worldPalmNormalDir * centerToSurfaceDistance);
                specialPoints.palmCenterPoint.original.rotation = Quaternion.LookRotation(Vector3.Cross(centerToWristDir, frontFingerCenterToIndex1Dir), frontFingerCenterToIndex1Dir);
            }

            if (!specialPoints.palmNormalPoint.original)
            {
                specialPoints.palmNormalPoint.original          = BasicHelpers.InstantiateEmptyChild(wrist.gameObject, "PalmNormal." + side.ToString()).transform;
                specialPoints.palmNormalPoint.original.position = worldPalmCenterPos + (worldPalmNormalDir * centerToSurfaceDistance);
                specialPoints.palmNormalPoint.original.rotation = Quaternion.LookRotation(worldPalmNormalDir, frontFingerCenterToIndex1Dir);
            }

            if (!specialPoints.palmInteriorPoint.original)
            {
                specialPoints.palmInteriorPoint.original          = BasicHelpers.InstantiateEmptyChild(wrist.gameObject, "PalmInterior." + side.ToString()).transform;
                specialPoints.palmInteriorPoint.original.rotation = specialPoints.palmCenterPoint.original.rotation;
                specialPoints.palmInteriorPoint.original.position = specialPoints.palmCenterPoint.original.position + frontFingerCenterToIndex;
            }

            if (!specialPoints.palmExteriorPoint.original)
            {
                specialPoints.palmExteriorPoint.original          = BasicHelpers.InstantiateEmptyChild(wrist.gameObject, "PalmExterior." + side.ToString()).transform;
                specialPoints.palmExteriorPoint.original.rotation = specialPoints.palmCenterPoint.original.rotation;
                specialPoints.palmExteriorPoint.original.position = specialPoints.palmCenterPoint.original.position - frontFingerCenterToIndex;
            }

            if (!specialPoints.rayPoint.original)
            {
                specialPoints.rayPoint.original          = BasicHelpers.InstantiateEmptyChild(wrist.gameObject, "Ray." + side.ToString()).transform;
                specialPoints.rayPoint.original.position = specialPoints.palmCenterPoint.original.position;
                specialPoints.rayPoint.original.rotation = specialPoints.palmNormalPoint.original.rotation;
            }

            if (!specialPoints.pinchCenterPoint.original)
            {
                specialPoints.pinchCenterPoint.original = BasicHelpers.InstantiateEmptyChild(wrist.gameObject, "PinchCenter." + side.ToString()).transform;
            }

            if (!specialPoints.throatCenterPoint.original)
            {
                specialPoints.throatCenterPoint.original = BasicHelpers.InstantiateEmptyChild(wrist.gameObject, "ThroatCenter." + side.ToString()).transform;
            }

            PositionConstraint pinchPosConstraint = specialPoints.pinchCenterPoint.original.GetComponent <PositionConstraint>();
            LookAtConstraint   pinchRotConstraint = specialPoints.pinchCenterPoint.original.GetComponent <LookAtConstraint>();

            PositionConstraint throatPosConstraint = specialPoints.throatCenterPoint.original.GetComponent <PositionConstraint>();
            LookAtConstraint   throatRotConstraint = specialPoints.throatCenterPoint.original.GetComponent <LookAtConstraint>();

            ConstraintSource indexTipSource = new ConstraintSource();

            indexTipSource.sourceTransform = indexTip;
            indexTipSource.weight          = 1.0f;

            ConstraintSource index1Source = new ConstraintSource();

            index1Source.sourceTransform = index1;
            index1Source.weight          = 1.0f;

            ConstraintSource thumbTipSource = new ConstraintSource();

            thumbTipSource.sourceTransform = thumbTip;
            thumbTipSource.weight          = 1.0f;

            ConstraintSource thumb1Source = new ConstraintSource();

            thumb1Source.sourceTransform = thumb1;
            thumb1Source.weight          = 1.0f;

            if (pinchPosConstraint == null)
            {
                pinchPosConstraint = specialPoints.pinchCenterPoint.original.gameObject.AddComponent <PositionConstraint>();
                pinchPosConstraint.constraintActive = true;
                pinchPosConstraint.AddSource(indexTipSource);
                pinchPosConstraint.AddSource(thumbTipSource);

                pinchPosConstraint.locked            = false;
                pinchPosConstraint.translationOffset = pinchPosConstraint.translationAtRest = Vector3.zero;
                pinchPosConstraint.locked            = true;
            }

            if (pinchRotConstraint == null)
            {
                pinchRotConstraint = specialPoints.pinchCenterPoint.original.gameObject.AddComponent <LookAtConstraint>();
                pinchRotConstraint.constraintActive = true;
                pinchRotConstraint.AddSource(indexTipSource);

                pinchRotConstraint.locked         = false;
                pinchRotConstraint.rotationOffset = pinchRotConstraint.rotationAtRest = Vector3.zero;
                pinchRotConstraint.locked         = true;
            }

            if (throatPosConstraint == null)
            {
                throatPosConstraint = specialPoints.throatCenterPoint.original.gameObject.AddComponent <PositionConstraint>();
                throatPosConstraint.constraintActive = true;
                throatPosConstraint.AddSource(index1Source);
                throatPosConstraint.AddSource(thumb1Source);

                throatPosConstraint.locked            = false;
                throatPosConstraint.translationOffset = throatPosConstraint.translationAtRest = Vector3.zero;
                throatPosConstraint.locked            = true;
            }

            if (throatRotConstraint == null)
            {
                throatRotConstraint = specialPoints.throatCenterPoint.original.gameObject.AddComponent <LookAtConstraint>();
                throatRotConstraint.constraintActive = true;
                throatRotConstraint.AddSource(indexTipSource);

                throatRotConstraint.locked         = false;
                throatRotConstraint.rotationOffset = throatRotConstraint.rotationAtRest = Vector3.zero;
                throatRotConstraint.locked         = true;
            }
        }
Beispiel #14
0
    void FixHand(HandModel handModel, Side side, Transform wristOffset)
    {
        // Check errors
        if (handModel.fingers.Length == 0)
        {
            Debug.LogError("Fingers array is empty!");
            return;
        }

        // Not all hands need an offset
        if (!wristOffset)
        {
            wristOffset = handModel.wrist.transformRef;
        }

        // Pinch center
        if (!handModel.pinchCenter)
        {
            GameObject pinchCenter = BasicHelpers.InstantiateEmptyChild(handModel.wrist.transformRef.parent.gameObject);
            pinchCenter.name = "PinchCenter";

            PositionConstraint pinchPosConstraint = pinchCenter.AddComponent <PositionConstraint>();

            ConstraintSource indexTipSource = new ConstraintSource();
            indexTipSource.sourceTransform = handModel.index.fingerTip;
            indexTipSource.weight          = 1.0f;

            ConstraintSource thumbTipSource = new ConstraintSource();
            thumbTipSource.sourceTransform = handModel.thumb.fingerTip;
            thumbTipSource.weight          = 1.0f;

            pinchPosConstraint.AddSource(indexTipSource);
            pinchPosConstraint.AddSource(thumbTipSource);

            pinchPosConstraint.translationOffset = Vector3.zero;

            pinchPosConstraint.constraintActive = true;

            handModel.pinchCenter = pinchCenter.transform;
        }

        // Throat center
        if (!handModel.throatCenter)
        {
            GameObject throatCenter = BasicHelpers.InstantiateEmptyChild(handModel.wrist.transformRef.parent.gameObject);
            throatCenter.name = "ThroatCenter";

            PositionConstraint throatPosConstraint = throatCenter.AddComponent <PositionConstraint>();

            ConstraintSource indexBaseSource = new ConstraintSource();
            indexBaseSource.sourceTransform = handModel.index.fingerBase;
            indexBaseSource.weight          = 1.0f;

            ConstraintSource thumbBaseSource = new ConstraintSource();
            thumbBaseSource.sourceTransform = handModel.thumb.fingerBase;
            thumbBaseSource.weight          = 1.0f;

            throatPosConstraint.AddSource(indexBaseSource);
            throatPosConstraint.AddSource(thumbBaseSource);

            throatPosConstraint.translationOffset = Vector3.zero;

            throatPosConstraint.constraintActive = true;

            handModel.throatCenter = throatCenter.transform;
        }

        // meanPoint
        meanPoint = Vector3.zero;
        for (int f = 0; f < handModel.fingers.Length; f++)
        {
            meanPoint += handModel.fingers[f].fingerBase.position;
        }
        meanPoint = meanPoint / handModel.fingers.Length;

        // palmRadius
        float meanDistance = 0.0f;

        for (int f = 0; f < handModel.fingers.Length; f++)
        {
            meanDistance += Vector3.Distance(meanPoint, handModel.fingers[f].fingerBase.position);
        }
        meanDistance = meanDistance / handModel.fingers.Length;
        palmRadius   = meanDistance;

        // Palm center
        if (!handModel.palmCenter)
        {
            GameObject palmCenter = BasicHelpers.InstantiateEmptyChild(wristOffset.gameObject);
            palmCenter.name = "PalmCenter";

            palmCenter.transform.position = meanPoint;

            if (side == Side.L)
            {
                palmCenter.transform.position     += new Vector3(0.0f, fingerRadius, 0.0f);
                palmCenter.transform.localRotation = Quaternion.Euler(new Vector3(-90.0f, 0.0f, 0.0f));
            }
            else
            {
                palmCenter.transform.position     -= new Vector3(0.0f, fingerRadius, 0.0f);
                palmCenter.transform.localRotation = Quaternion.Euler(new Vector3(-90.0f, 0.0f, 180.0f));
            }

            handModel.palmCenter = palmCenter.transform;
        }

        // Palm normal (depends on palmCenter)
        if (!handModel.palmNormal)
        {
            GameObject palmNormal = BasicHelpers.InstantiateEmptyChild(wristOffset.gameObject);
            palmNormal.name = "PalmNormal";

            palmNormal.transform.position = handModel.palmCenter.position;

            if (side == Side.L)
            {
                palmNormal.transform.localRotation = Quaternion.Euler(new Vector3(-90.0f, 0.0f, 0.0f));
            }
            else
            {
                palmNormal.transform.localRotation = Quaternion.Euler(new Vector3(90.0f, 0.0f, 0.0f));
            }

            handModel.palmNormal = palmNormal.transform;
        }

        // Palm interior/exterior (depend on PalmCenter and palmRadius)
        if (!handModel.palmInterior)
        {
            GameObject palmInterior = BasicHelpers.InstantiateEmptyChild(wristOffset.gameObject);
            palmInterior.name = "PalmInterior";

            palmInterior.transform.position = handModel.palmCenter.position;
            palmInterior.transform.rotation = handModel.palmCenter.rotation;

            palmInterior.transform.position += handModel.palmCenter.up * palmRadius;

            handModel.palmInterior = palmInterior.transform;
        }
        if (!handModel.palmExterior)
        {
            GameObject palmExterior = BasicHelpers.InstantiateEmptyChild(wristOffset.gameObject);
            palmExterior.name = "PalmExterior";

            palmExterior.transform.position = handModel.palmCenter.position;
            palmExterior.transform.rotation = handModel.palmCenter.rotation;

            palmExterior.transform.position -= handModel.palmCenter.up * palmRadius;

            handModel.palmExterior = palmExterior.transform;
        }

        // Ray line (depend on PalmCenter)
        if (!handModel.ray)
        {
            GameObject ray = BasicHelpers.InstantiateEmptyChild(wristOffset.gameObject);
            ray.name = "Ray";

            ray.transform.position = handModel.palmCenter.position;

            LineRenderer lineRenderer = ray.AddComponent <LineRenderer>();
            lineRenderer.useWorldSpace = false;
            lineRenderer.SetPositions(new Vector3[] { Vector3.zero, new Vector3(0.0f, 0.0f, 0.5f) });
            lineRenderer.material   = rayMat;
            lineRenderer.startWidth = rayWidth;
            lineRenderer.endWidth   = rayWidth;

            handModel.ray = ray.transform;
        }

        if (handModel is SlaveHandModel)
        {
            SlaveHandModel slaveHandModel = handModel as SlaveHandModel;

            // Palm trigger (depend on PalmCenter and palmRadius)
            if (!slaveHandModel.palmTrigger)
            {
                GameObject palmTrigger = BasicHelpers.InstantiateEmptyChild(wristOffset.gameObject);
                palmTrigger.name = "PalmTrigger";

                palmTrigger.transform.position = handModel.palmCenter.position;

                SphereCollider trigger = palmTrigger.AddComponent <SphereCollider>();
                trigger.isTrigger = true;
                trigger.radius    = palmRadius;

                TriggerNotifier notifier = palmTrigger.AddComponent <TriggerNotifier>();
                notifier.ignoreChildren = handModel.wrist.transformRef.parent;

                slaveHandModel.palmTrigger = notifier;
            }

            // Hand trigger (depend on PalmCenter and palmRadius)
            if (!slaveHandModel.handTrigger)
            {
                GameObject handTrigger = BasicHelpers.InstantiateEmptyChild(wristOffset.gameObject);
                handTrigger.name = "HandTrigger";

                handTrigger.transform.position = handModel.palmCenter.position;

                SphereCollider trigger = handTrigger.AddComponent <SphereCollider>();
                trigger.isTrigger = true;
                trigger.radius    = Vector3.Distance(meanPoint, BasicHelpers.FurthestPoint(meanPoint, GetFingerTips(slaveHandModel))) + 0.02f;

                TriggerNotifier notifier = handTrigger.AddComponent <TriggerNotifier>();
                notifier.ignoreChildren = handModel.wrist.transformRef.parent;

                slaveHandModel.handTrigger = notifier;
            }
        }

        // Colliders, Rigidbodies and Joitsn if needed
        if (handModel is SlaveHandModel)
        {
            // Setup colliders, rbs and joints for slave
            SetupPhysics(handModel as SlaveHandModel, wristOffset, meanPoint, palmRadius, fingerRadius);
        }
    }