using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using System.Linq; namespace Redeyes { public class DiviningLipsAndHands : MVRScript { protected bool isSceneLoaded = false; protected struct PersonInfo { public Atom PersonAtom; public bool IsFemale; public Component atomRHand, atomLHand, atomMouth, atomLThigh, atomRThigh, penisMidControl; public DAZMorph Right_Fingers_Grasp, Right_Thumb_Bend, Right_Thumb_Grasp, Right_Thumb_in_out; public DAZMorph Left_Fingers_Grasp, Left_Thumb_Bend, Left_Thumb_Grasp, Left_Thumb_in_out; public DAZMorph Pussy_Fingers_R, Pussy_Fingers_L, Pussy_Fingers_Bend_R, Pussy_Fingers_Bend_L; public DAZMorph Pussy_Fingers2_R, Pussy_Fingers2_L, Pussy_Fingers2_Bend_R, Pussy_Fingers2_Bend_L; public DAZMorph Mouth_Wide_Open, Lips_Close, Lip_Bottom_UP; public DAZMorph BJ_DX_Mouth_Open_Shape, BJ_DX_Mouth_Suck_Shape_1, BJ_DX_Mouth_Suck_Shape_2, BJ_DX_Kiss_2; public DAZMorph BJ_DX_Mouth_Corner_Depth_L, BJ_DX_Mouth_Corner_Depth_R, BJ_DX_Cheek_Corner_Depth_L, BJ_DX_Cheek_Corner_Depth_R; public DAZMorph BJ_DX_Mouth_Corner_Height_L, BJ_DX_Mouth_Corner_Height_R, BJ_DX_Cheek_Corner_Width_L, BJ_DX_Cheek_Corner_Width_R; public DAZMorph Tongue_In_Out, Tongue_Side_Side, Tongue_Bend, Tongue_Narrow_Wide, Tongue_Thickness; } protected List ListOfPersonAtoms = new List(); protected Component potentialRHandTarget, potentialRHandTIPTarget; protected Component potentialLHandTarget, potentialLHandTIPTarget; protected Component potentialMouthTarget; protected float potentialTargetAmount; protected float potentialRHandTargetDistance, potentialABSRHandTargetDistance; protected float potentialLHandTargetDistance, potentialABSLHandTargetDistance; protected float potentialMouthTargetDistance; protected float potentialTongueTargetDistance; protected bool targetWithinDistance; protected string MouthTargetType="penis"; protected string rHandTargetType="penis"; protected string lHandTargetType="penis"; protected float _targetDistance; protected Atom _targetAtom = null; protected float _targetTipToBaseDistance, _tmpPotentialDistance, _tmpPotentialDistance2; protected float hand_grasp_a, hand_grasp_b; protected float thumb_grasp_a, thumb_grasp_b; protected float thumb_bend_a, thumb_bend_b; protected float thumb_bend_start, thumb_bend_end; protected float hand_grasp_start, hand_grasp_end; protected float mouth_open_a, mouth_open_b; protected float mouth_suck_a, mouth_suck_b; protected float tongue_a, tongue_b; protected float mouth_open_start, mouth_open_end; protected float hand_grasp_amount, thumb_grasp_amount, thumb_bend_amount, mouth_amount, tongue_amount; protected float tmp_object_offset; protected JSONStorableBool _handGraspEnabledJSON = new JSONStorableBool("Hand Grasp", true); protected JSONStorableBool _disableFingerControlPossessJSON = new JSONStorableBool("Disable finger control on possess", true); protected JSONStorableBool _enablePossessTitGrabJSON = new JSONStorableBool("Allow Possess Tit Grab", true); protected JSONStorableBool _lipsSuckEnabledJSON = new JSONStorableBool("Lips suck", true); protected JSONStorableBool _lips2ndAnimationEnabledJSON = new JSONStorableBool("Lips 2nd animation", true); protected JSONStorableBool _TonguePlayEnabledJSON = new JSONStorableBool("Tongue Play", true); protected JSONStorableBool _TongueLickRangePointEnabledJSON = new JSONStorableBool("Tongue Lick at Range Point", true); protected JSONStorableBool _handGraspAnyGenderEnabledJSON = new JSONStorableBool("Hand Grasp Any Gender", false); protected JSONStorableStringChooser _vagFingeringChooser; protected List _vagFingeringChoices = new List(); protected string _vagFingeringSelection; protected JSONStorableFloat _morpheChangeRangeJSON, _morpheNippleChangeRangeJSON; protected JSONStorableFloat _handGraspRangeJSON, _vagHandRangeJSON, _vagFingeringRangeJSON, _thumbGraspRangeJSON, _thumbBendRangeJSON; protected JSONStorableFloat DildoOffsetJSON; protected JSONStorableFloat _hand_grasp_amountJSON, _hand_tit_grasp_amountJSON, _vag_fingers_amountJSON, _thumb_Bend_amountJSON; protected JSONStorableFloat _cylinderRadiusAmountJSON, _cylinderHeightAmountJSON; protected JSONStorableFloat _vag_fingers_speedJSON, Fingering_minmaxJSON; protected JSONStorableFloat _BJ_DX_Mouth_Suck_Shape_2_speedJSON, _BJ_tongue_in_out_speedJSON, _cock_lick_speedJSON; protected JSONStorableFloat _vagina_lick_speedJSON, _vagina_tongue_in_out_speedJSON; protected JSONStorableFloat _kiss_tongue_in_out_speedJSON, _kiss_tongue_bend_speedJSON; protected JSONStorableFloat _mouthOpenRangeJSON, _suckRangeJSON, _tonguePenisLickRangeJSON; protected JSONStorableFloat _tongueNippleLickRangeJSON, _tongueMouthKissRangeJSON; protected JSONStorableFloat Mouth_Open_Wide_Amount_JSON, BJ_DX_Mouth_Suck_Shape_1_AMOUNT_JSON, lips_close_amountJSON, BJ_DX_Mouth_Suck_Shape_2_minmaxJSON; protected JSONStorableFloat Tongue_in_out_minmaxJSON, Tongue_side_minmaxJSON; protected JSONStorableFloat _minTargetDistanceJSON; protected JSONStorableFloat _mouthOffsetXJSON, _mouthOffsetYJSON, _mouthOffsetZJSON; protected JSONStorableFloat _handOffsetXJSON, _handOffsetYJSON, _handOffsetZJSON; protected JSONStorableFloat _VaginaOffsetXJSON, _VaginaOffsetYJSON, _VaginaOffsetZJSON; protected JSONStorable js; protected DAZCharacterSelector dcs; protected GenerateDAZMorphsControlUI morphUI; protected Vector3 yzDirection; protected Vector3 xToY; protected Vector3 projection; protected float BJ_DX_Mouth_Suck_Shape_2_speed = 2.0f; protected float BJ_lerpValue; protected float BJ_timer; protected float fingers_speed = 2.0f; protected float fingers_lerpValue; protected float fingers_timer; protected float Tongue_inout_speed = 2.0f; protected float Tongue_inout_lerpValue; protected float Tongue_inout_timer; protected float Tongue_speed = 2.0f; protected float Tongue_speed2 = 2.0f; protected float Tongue_lerpValue, Tongue_lerpValue2; protected float Kissing_lerpValue, Kissing_lerpValue2; protected float Kissing_speed = 2.0f; protected float Kissing_speed2 = 2.0f; protected float Tongue_timer, Tongue_timer2; protected float Kissing_timer; protected float forwardBackwardRatio = 0.5f; protected bool isMovingForward = true; protected float proportion; protected float nipple_mouth_offset = 0.12f; protected float nipple_suck_offset = 0.10f; protected float nipple_suck_animation_offset; protected float mouth_mouth_offset = 0.12f; protected float mouth_suck_offset = 0.08f; protected float vag_mouth_offset = 0.015f; protected float vag_suck_offset = 0.015f; protected float alignmentThreshold = 45f; protected float angleDifference; protected string alignment; protected Quaternion rotationDifference; protected Vector3 eulerDifference; protected Vector3 offset, axis; protected float cylinderProjection, lateralDistance; public bool IsTargetInCylinder(Transform testTarget, Transform BaseTarget) { // Calculate offset from cylinder bottom to vertex offset = testTarget.position - BaseTarget.position; //axis = (BaseTarget.rotation * Quaternion.Euler(90, 180, 0)).eulerAngles; axis = BaseTarget.up; // Project offset onto cylinder axis cylinderProjection = Vector3.Dot(offset, axis); // Check if vertex is vertically within the cylinder's bounds // Calculate distance from the projected point on axis to cylinder's axis lateralDistance = Vector2.Distance(new Vector2(offset.x, offset.z), new Vector2(axis.x, axis.z) * cylinderProjection); if (cylinderProjection >= -(_cylinderHeightAmountJSON.val) && cylinderProjection <= (_cylinderHeightAmountJSON.val) && lateralDistance <= _cylinderRadiusAmountJSON.val) { //SuperController.LogMessage(testTarget.position + " " + BaseTarget.position + " v " + cylinderProjection + " radius " + lateralDistance + " inside cylinder"); return true; } else { //SuperController.LogMessage(testTarget.position + " " + BaseTarget.position + " v " + cylinderProjection + " radius " + lateralDistance + " Vertex is outside bounds"); return false; } } /*public static bool IsFemale(Atom person) { bool retVal = true; DAZCharacter character = person.GetComponentInChildren(); if (character != null) { retVal = !character.isMale; } return retVal; }*/ protected void syncPersonAtoms() { if(isSceneLoaded) { //SuperController.LogMessage("syncPersonAtoms"); ListOfPersonAtoms = new List(); // empty list List tmp_ListOfPersonAtoms; tmp_ListOfPersonAtoms = SuperController.singleton.GetAtoms().Where(atom => atom.type == "Person" || atom.type == "Dildo").ToList(); ListOfPersonAtoms.Clear(); foreach (Atom personAtom in tmp_ListOfPersonAtoms) { PersonInfo personInfo; personInfo.PersonAtom = personAtom; if (personAtom.type == "Person") { //personInfo.IsFemale = IsFemale(personAtom); personInfo.atomRHand = personAtom.rigidbodies.First(rb => rb.name == "rHand"); personInfo.atomLHand = personAtom.rigidbodies.First(rb => rb.name == "lHand"); personInfo.atomMouth = personAtom.rigidbodies.First(rb => rb.name == "LipTrigger"); personInfo.atomLThigh = personAtom.freeControllers.First(fc => fc.name == "lThighControl"); personInfo.atomRThigh = personAtom.freeControllers.First(fc => fc.name == "rThighControl"); personInfo.penisMidControl = personAtom.freeControllers.First(fc => fc.name == "penisMidControl"); js = personAtom.GetStorableByID("geometry"); dcs = js as DAZCharacterSelector; morphUI = dcs.morphsControlUI; personInfo.Right_Fingers_Grasp = morphUI.GetMorphByDisplayName("Penis_Grip_R"); personInfo.Right_Thumb_Bend = morphUI.GetMorphByDisplayName("Right Thumb Bend"); personInfo.Right_Thumb_Grasp = morphUI.GetMorphByDisplayName("Right Thumb Grasp"); personInfo.Right_Thumb_in_out = morphUI.GetMorphByDisplayName("Right Thumb In-Out"); personInfo.Left_Fingers_Grasp = morphUI.GetMorphByDisplayName("Penis Grip L"); personInfo.Left_Thumb_Bend = morphUI.GetMorphByDisplayName("Left Thumb Bend"); personInfo.Left_Thumb_Grasp = morphUI.GetMorphByDisplayName("Left Thumb Grasp"); personInfo.Left_Thumb_in_out = morphUI.GetMorphByDisplayName("Left Thumb In-Out"); personInfo.Pussy_Fingers_R = morphUI.GetMorphByDisplayName("Pussy Finger.R"); personInfo.Pussy_Fingers_L = morphUI.GetMorphByDisplayName("Pussy Finger.L"); personInfo.Pussy_Fingers_Bend_R = morphUI.GetMorphByDisplayName("Pussy Finger Bend.R"); personInfo.Pussy_Fingers_Bend_L = morphUI.GetMorphByDisplayName("Pussy Finger Bend.L"); personInfo.Pussy_Fingers2_R = morphUI.GetMorphByDisplayName("Pussy-Finger2.R"); personInfo.Pussy_Fingers2_L = morphUI.GetMorphByDisplayName("Pussy-Finger2.L"); personInfo.Pussy_Fingers2_Bend_R = morphUI.GetMorphByDisplayName("Pussy-Finger2_Bend.R"); personInfo.Pussy_Fingers2_Bend_L = morphUI.GetMorphByDisplayName("Pussy-Finger2_Bend.L"); personInfo.Mouth_Wide_Open = morphUI.GetMorphByDisplayName("Mouth Open Wide"); personInfo.BJ_DX_Mouth_Open_Shape = morphUI.GetMorphByDisplayName("[BJ DX] Mouth Open Shape"); personInfo.BJ_DX_Mouth_Suck_Shape_1 = morphUI.GetMorphByDisplayName("[BJ DX] Mouth Suck Shape 1"); personInfo.BJ_DX_Mouth_Suck_Shape_2 = morphUI.GetMorphByDisplayName("[BJ DX] Mouth Suck Shape 2"); personInfo.BJ_DX_Kiss_2 = morphUI.GetMorphByDisplayName("BJ DX Kiss 2"); personInfo.BJ_DX_Mouth_Corner_Depth_L = morphUI.GetMorphByDisplayName("[BJ DX] Mouth Corner Depth L"); personInfo.BJ_DX_Mouth_Corner_Depth_R = morphUI.GetMorphByDisplayName("[BJ DX] Mouth Corner Depth R"); personInfo.BJ_DX_Cheek_Corner_Depth_L = morphUI.GetMorphByDisplayName("[BJ DX] Cheek Corner Bulge L"); personInfo.BJ_DX_Cheek_Corner_Depth_R = morphUI.GetMorphByDisplayName("[BJ DX] Cheek Corner Bulge R"); personInfo.BJ_DX_Mouth_Corner_Height_L = morphUI.GetMorphByDisplayName("[BJ DX] Mouth Corner Height L"); personInfo.BJ_DX_Mouth_Corner_Height_R = morphUI.GetMorphByDisplayName("[BJ DX] Mouth Corner Height R"); personInfo.BJ_DX_Cheek_Corner_Width_L = morphUI.GetMorphByDisplayName("[BJ DX] Mouth Corner Width L"); personInfo.BJ_DX_Cheek_Corner_Width_R = morphUI.GetMorphByDisplayName("[BJ DX] Mouth Corner Width R"); personInfo.Tongue_In_Out = morphUI.GetMorphByDisplayName("Tongue In-Out"); personInfo.Tongue_Side_Side = morphUI.GetMorphByDisplayName("Tongue Side-Side"); personInfo.Tongue_Bend = morphUI.GetMorphByDisplayName("Tongue Bend Tip"); personInfo.Tongue_Narrow_Wide = morphUI.GetMorphByDisplayName("Tongue Narrow-Wide"); personInfo.Tongue_Thickness = morphUI.GetMorphByDisplayName("Tongue Thickness"); if (morphUI.GetMorphByDisplayName("Lips Close") == null || morphUI.GetMorphByDisplayName("Lip Bottom Up") == null) { personInfo.IsFemale=false; personInfo.Lips_Close = null; personInfo.Lip_Bottom_UP = null; } else { personInfo.IsFemale=true; personInfo.Lips_Close = morphUI.GetMorphByDisplayName("Lips Close"); personInfo.Lip_Bottom_UP = morphUI.GetMorphByDisplayName("Lip Bottom Up"); } if (personInfo.Mouth_Wide_Open == null || personInfo.BJ_DX_Mouth_Open_Shape == null || personInfo.BJ_DX_Mouth_Suck_Shape_1 == null || personInfo.BJ_DX_Mouth_Suck_Shape_2 == null || personInfo.BJ_DX_Kiss_2 == null || personInfo.BJ_DX_Mouth_Corner_Depth_L ==null || personInfo.BJ_DX_Mouth_Corner_Depth_R == null || personInfo.BJ_DX_Cheek_Corner_Depth_L ==null || personInfo.BJ_DX_Cheek_Corner_Depth_R == null || personInfo.BJ_DX_Mouth_Corner_Height_L == null || personInfo.BJ_DX_Mouth_Corner_Height_R == null || personInfo.BJ_DX_Cheek_Corner_Width_L == null || personInfo.BJ_DX_Cheek_Corner_Width_R == null || personInfo.Pussy_Fingers_R == null || personInfo.Pussy_Fingers_L == null || personInfo.Pussy_Fingers_Bend_R == null || personInfo.Pussy_Fingers_Bend_L == null || personInfo.Pussy_Fingers2_R == null || personInfo.Pussy_Fingers2_L == null || personInfo.Pussy_Fingers2_Bend_R == null || personInfo.Pussy_Fingers2_Bend_L == null || personInfo.Right_Fingers_Grasp == null || personInfo.Left_Fingers_Grasp == null) { SuperController.LogError("Missing 1 or more of the following morphes -> \nhttps://hub.virtamate.com/resources/bj-deluxe.23492/ -> AnalogueBob.BJ_Deluxe.2.var \nhttps://hub.virtamate.com/resources/penis-grip.849/ -> Vamtastic.Penis_Grip_V3.1.var\nhttps://hub.virtamate.com/resources/pussy-fingers.1901/ Vamtastic.Pussy_Fingers.1.var\nhttps://hub.virtamate.com/resources/pussy-fingers-2.1934/ -> VamTastic.Pussy_Fingers2.1.var\nPLEASE DOWNLOAD ALL DEPENDENCIES"); DestroyImmediate(this); return; } } else { personInfo.IsFemale = false; personInfo.atomRHand = null; personInfo.atomLHand = null; personInfo.atomMouth = null; personInfo.atomLThigh = null; personInfo.atomRThigh = null; personInfo.penisMidControl = null; personInfo.Right_Fingers_Grasp = null; //personInfo.Right_Thumb_Fist = null; //personInfo.Right_Thumb_In_Out = null; personInfo.Right_Thumb_Bend = null; personInfo.Right_Thumb_Grasp = null; personInfo.Right_Thumb_in_out = null; personInfo.Left_Fingers_Grasp = null; //personInfo.Left_Thumb_Fist = null; //personInfo.Left_Thumb_In_Out = null; personInfo.Left_Thumb_Bend = null; personInfo.Left_Thumb_Grasp = null; personInfo.Left_Thumb_in_out = null; personInfo.Pussy_Fingers_R = null; personInfo.Pussy_Fingers_L = null; personInfo.Pussy_Fingers_Bend_R = null; personInfo.Pussy_Fingers_Bend_L =null; personInfo.Pussy_Fingers2_R = null; personInfo.Pussy_Fingers2_L = null; personInfo.Pussy_Fingers2_Bend_R = null; personInfo.Pussy_Fingers2_Bend_L =null; personInfo.Mouth_Wide_Open = null; personInfo.BJ_DX_Mouth_Open_Shape = null; personInfo.BJ_DX_Mouth_Suck_Shape_1 = null; personInfo.BJ_DX_Mouth_Suck_Shape_2 = null; personInfo.BJ_DX_Kiss_2 = null; personInfo.BJ_DX_Mouth_Corner_Depth_L = null; personInfo.BJ_DX_Mouth_Corner_Depth_R = null; personInfo.BJ_DX_Cheek_Corner_Depth_L = null; personInfo.BJ_DX_Cheek_Corner_Depth_R = null; personInfo.BJ_DX_Mouth_Corner_Height_L = null; personInfo.BJ_DX_Mouth_Corner_Height_R = null; personInfo.BJ_DX_Cheek_Corner_Width_L = null; personInfo.BJ_DX_Cheek_Corner_Width_R = null; personInfo.Tongue_In_Out = null; personInfo.Tongue_Side_Side = null; personInfo.Tongue_Bend = null; personInfo.Lips_Close = null; personInfo.Lip_Bottom_UP = null; personInfo.Tongue_Narrow_Wide = null; personInfo.Tongue_Thickness = null; } ListOfPersonAtoms.Add(personInfo); } } } // Create VaM-UI Float slider public static JSONStorableFloat SetupSlider(MVRScript script, string format, string label, float defaultValue, float minValue, float maxValue, bool rightSide) { JSONStorableFloat storable = new JSONStorableFloat(label, defaultValue, minValue, maxValue, true, true); storable.storeType = JSONStorableParam.StoreType.Full; UIDynamicSlider slidertmp = script.CreateSlider(storable, rightSide); slidertmp.valueFormat = format; script.RegisterFloat(storable); return storable; } public override void Init() { UIDynamicTextField text = null; try { foreach (var storable in SuperController.singleton .GetComponentInChildren() .GetComponentsInChildren() .Where(s => s.name.Contains("Redeyes.DiviningLipsAndHands"))) { if(containingAtom.type == "CoreControl") { SuperController.LogMessage($"Redeyes.DiviningLipsAndHands already running as a session plugin - exiting as scene plugin"); DestroyImmediate(this); return; } } if (containingAtom.type != "CoreControl" && containingAtom.type != "SessionPluginManager") { SuperController.LogError($"Please load DiviningLipsAndHands as a Session or Scene Plugin, not with a '{containingAtom.type}' atom."); DestroyImmediate(this); return; } SuperController.singleton.onSceneLoadedHandlers += OnSceneLoaded; SuperController.singleton.onAtomUIDsChangedHandlers += OnAtomUIDsChanged; SuperController.LogMessage("Starting DiviningLipsAndHands"); // LEFT SIDE _handGraspEnabledJSON.storeType = JSONStorableParam.StoreType.Full; _handGraspEnabledJSON.setCallbackFunction += (bool isChecked) => { cleanup(); }; RegisterBool(_handGraspEnabledJSON); CreateToggle(_handGraspEnabledJSON, false); _vagFingeringChoices.Add("Off"); _vagFingeringChoices.Add("Fingering Morph 1"); _vagFingeringChoices.Add("Fingering Morph 2"); _vagFingeringChoices.Add("F1 Horizontal F2 Vertical"); _vagFingeringChoices.Add("F1 Vertical F2 Horizontal "); _vagFingeringChooser = new JSONStorableStringChooser("Vagina Fingering", _vagFingeringChoices, "F1 Vertical F2 Horizontal ", "Vagina Fingering",(string name) => { cleanup(); }); RegisterStringChooser(_vagFingeringChooser); UIDynamicPopup _vagFingeringPopup = CreatePopup(_vagFingeringChooser, false); _disableFingerControlPossessJSON.storeType = JSONStorableParam.StoreType.Full; _disableFingerControlPossessJSON.setCallbackFunction += (bool isChecked) => { cleanup(); }; RegisterBool(_disableFingerControlPossessJSON); CreateToggle(_disableFingerControlPossessJSON, false); _enablePossessTitGrabJSON.storeType = JSONStorableParam.StoreType.Full; _enablePossessTitGrabJSON.setCallbackFunction += (bool isChecked) => { cleanup(); }; RegisterBool(_enablePossessTitGrabJSON); CreateToggle(_enablePossessTitGrabJSON, false); _handGraspAnyGenderEnabledJSON.storeType = JSONStorableParam.StoreType.Full; _handGraspAnyGenderEnabledJSON.setCallbackFunction += (bool isChecked) => { cleanup(); }; RegisterBool(_handGraspAnyGenderEnabledJSON); CreateToggle(_handGraspAnyGenderEnabledJSON, false); _handGraspRangeJSON = SetupSlider(this,"F2", "Hand Grasp Range", 0.15f, 0.05f, 1.0f, false); _thumbGraspRangeJSON = SetupSlider(this,"F2", "Thumb Grasp Range", 0.15f, 0.05f, 1.0f, false); _thumbBendRangeJSON = SetupSlider(this,"F2", "Thumb Bend Range", 0.07f, 0.0f, 1.0f, false); _hand_grasp_amountJSON = SetupSlider(this,"F2", "Hand Grasp Amount", 1.0f, 0.00f, 1.0f, false); _hand_tit_grasp_amountJSON = SetupSlider(this,"F2", "Hand Tit Grasp Amount", 0.6f, 0.00f, 1.0f, false); _thumb_Bend_amountJSON = SetupSlider(this,"F2", "Thumb Bend Amount", 0.45f, 0.00f, 1.0f, false); _vagHandRangeJSON = SetupSlider(this,"F2", "Vagina Hand Range", 0.27f, 0.05f, 1.0f, false); _vagFingeringRangeJSON = SetupSlider(this,"F2", "Vagina Fingering Range", 0.20f, 0.05f, 1.0f, false); _vag_fingers_amountJSON = SetupSlider(this,"F2", "Fingering Hand Amount", 1.0f, 0.00f, 1.0f, false); Fingering_minmaxJSON = SetupSlider(this,"F2", "Animation Fingering Vagina Amount", 0.5f, 0.0f, 2.0f, false); _vag_fingers_speedJSON = SetupSlider(this,"F2", "Fingering animation speed", 3.0f, 0.00f, 5.0f, false); _cylinderRadiusAmountJSON = SetupSlider(this,"F3", "Pussy Hands React Radius Amount", 0.08f, 0.0f, 1.0f, false); _cylinderHeightAmountJSON = SetupSlider(this,"F3", "Pussy Hands React Height Amount", 0.40f, 0.00f, 1.00f, false); // RIGHT SIDE _lipsSuckEnabledJSON.storeType = JSONStorableParam.StoreType.Full; _lipsSuckEnabledJSON.setCallbackFunction += (bool isChecked) => { cleanup(); }; RegisterBool(_lipsSuckEnabledJSON); CreateToggle(_lipsSuckEnabledJSON, true); _lips2ndAnimationEnabledJSON.storeType = JSONStorableParam.StoreType.Full; _lips2ndAnimationEnabledJSON.setCallbackFunction += (bool isChecked) => { cleanup(); }; RegisterBool(_lips2ndAnimationEnabledJSON); CreateToggle(_lips2ndAnimationEnabledJSON, true); _TonguePlayEnabledJSON.storeType = JSONStorableParam.StoreType.Full; _TonguePlayEnabledJSON.setCallbackFunction += (bool isChecked) => { cleanup(); }; RegisterBool(_TonguePlayEnabledJSON); CreateToggle(_TonguePlayEnabledJSON, true); _mouthOpenRangeJSON = SetupSlider(this,"F2", "Mouth Open Range", 0.23f, 0.05f, 1.0f, true); _suckRangeJSON = SetupSlider(this,"F2", "Start Suck Range", 0.18f, 0.00f, 1.0f, true); _TongueLickRangePointEnabledJSON.storeType = JSONStorableParam.StoreType.Full; _TongueLickRangePointEnabledJSON.setCallbackFunction += (bool isChecked) => { cleanup(); }; RegisterBool(_TongueLickRangePointEnabledJSON); CreateToggle(_TongueLickRangePointEnabledJSON, true); _tonguePenisLickRangeJSON = SetupSlider(this,"F2", "Start Tongue penis lick Range", 0.13f, 0.00f, 1.0f, true); _tongueNippleLickRangeJSON = SetupSlider(this,"F3", "Start Tongue nipple lick Range", 0.025f, 0.000f, 1.0f, false); _tongueMouthKissRangeJSON = SetupSlider(this,"F3", "Start Tongue Mouth kiss Range", 0.035f, 0.000f, 1.0f, false); Mouth_Open_Wide_Amount_JSON = SetupSlider(this,"F2", "Mouth Open Wide amount", 1f, 0.0f, 2.0f, true); BJ_DX_Mouth_Suck_Shape_1_AMOUNT_JSON = SetupSlider(this,"F2", "BJ suck amount", 0.7f, 0.0f, 2.0f, true); lips_close_amountJSON = SetupSlider(this,"F2", "Lips closed amount", -0.5f, -2.0f, 1.0f, true); BJ_DX_Mouth_Suck_Shape_2_minmaxJSON = SetupSlider(this,"F2", "Lips dynamic suck Amount", 0.3f, 0.0f, 2.0f, true); Tongue_in_out_minmaxJSON = SetupSlider(this,"F2", "Tongue in/out dynamic Amount", 2.0f, 0.0f, 5.0f, true); Tongue_side_minmaxJSON = SetupSlider(this,"F2", "Tongue side to side dynamic Amount", 1.0f, 0.0f, 2.0f, true); _BJ_DX_Mouth_Suck_Shape_2_speedJSON = SetupSlider(this,"F2", "BJ animation speed", 3.0f, 0.00f, 5.0f, true); _BJ_tongue_in_out_speedJSON = SetupSlider(this,"F2", "BJ Tongue in out speed", 1.0f, 0.00f, 5.0f, true); _cock_lick_speedJSON = SetupSlider(this,"F2", "BJ cock lick speed", 6.5f, 0.00f, 10.0f, true); _vagina_lick_speedJSON = SetupSlider(this,"F2", "Vagina lick speed", 3.0f, 0.00f, 5.0f, true); _vagina_tongue_in_out_speedJSON = SetupSlider(this,"F2", "Vagina tongue in/out speed", 1.0f, 0.00f, 5.0f, true); _kiss_tongue_in_out_speedJSON = SetupSlider(this,"F2", "Kiss tongue in/out speed", 1.0f, 0.00f, 5.0f, true); _kiss_tongue_bend_speedJSON = SetupSlider(this,"F2", "Kiss tongue bend speed", 3.0f, 0.00f, 5.0f, true); CreateSpacer(false).height = 20f; CreateSpacer(true).height = 20f; DildoOffsetJSON = SetupSlider(this,"F2", "Dildo Offset", -0.02f, -0.5f, 0.5f, false); _morpheChangeRangeJSON = SetupSlider(this,"F2", "Morphe Range of Change", 0.04f, 0f, 0.1f, false); _morpheNippleChangeRangeJSON = SetupSlider(this,"F3", "Morphe Range Nipple", 0.015f, 0.000f, 0.100f, false); _minTargetDistanceJSON = SetupSlider(this,"F2", "Min Target Distance [cm]", 25f, 0f, 100f, false); CreateSpacer(false).height = 20f; CreateSpacer(true).height = 20f; _handOffsetXJSON = SetupSlider(this,"F2", "Hand Targeting Offset X [cm]", 7f, -10f, 10f, false); _handOffsetYJSON = SetupSlider(this,"F2", "Hand Targeting Offset Y [cm]", -1.6f, -10f, 10f, false); _handOffsetZJSON = SetupSlider(this,"F2", "Hand Targeting Offset Z [cm]", 2f, -10f, 10f, false); CreateSpacer(false).height = 20f; CreateSpacer(true).height = 20f; _mouthOffsetXJSON = SetupSlider(this,"F2", "Mouth Targeting Offset X [cm]", 0f, -10f, 10f, false); _mouthOffsetYJSON = SetupSlider(this,"F2", "Mouth Targeting Offset Y [cm]", -1.5f, -10f, 10f, false); _mouthOffsetZJSON = SetupSlider(this,"F2", "Mouth Targeting Offset Z [cm]", 0f, -10f, 10f, false); CreateSpacer(false).height = 20f; CreateSpacer(true).height = 20f; _VaginaOffsetXJSON = SetupSlider(this,"F2", "Vagina Targeting Offset X [cm]", 0f, 0f, 0f, false); _VaginaOffsetYJSON = SetupSlider(this,"F2", "Vagina Targeting Offset Y [cm]", 0f, 0f, 0f, false); _VaginaOffsetZJSON = SetupSlider(this,"F2", "Vagina Targeting Offset Z [cm]", 0f, 0f, 0f, false); CreateSpacer(false).height = 20f; CreateSpacer(true).height = 20f; StartCoroutine(WaitForLoadingComplete()); } catch (Exception e) { SuperController.LogError($"{nameof(DiviningLipsAndHands)}.{nameof(Init)}: {e}"); } } private IEnumerator WaitForLoadingComplete() { while (SuperController.singleton.isLoading) { isSceneLoaded = false; yield return null; } while (SuperController.singleton.freezeAnimation) { isSceneLoaded = false; yield return null; } yield return null; isSceneLoaded = true; syncPersonAtoms(); } private void OnSceneLoaded() { try { isSceneLoaded=true; syncPersonAtoms(); } catch (Exception e) { SuperController.LogError("Exception caught in OnSceneLoaded: " + e); } } private void OnAtomUIDsChanged(List atomUIDs) { try { if (!isSceneLoaded) return; var sctrl = SuperController.singleton; if (sctrl.isLoading) return; syncPersonAtoms(); } catch (Exception e) { SuperController.LogError("Exception caught in OnAtomUIDsChanged: " + e); } } public void OnEnable() { try { syncPersonAtoms(); //SuperController.LogMessage($"{nameof(DiviningLipsAndHands)} enabled"); } catch (Exception e) { SuperController.LogError($"{nameof(DiviningLipsAndHands)}.{nameof(OnEnable)}: {e}"); } } public void cleanup() { foreach (PersonInfo personInfo in ListOfPersonAtoms) { if (personInfo.PersonAtom.type == "Person") { personInfo.Right_Fingers_Grasp.morphValue = 0f; personInfo.Right_Thumb_Bend.morphValue = 0f; personInfo.Right_Thumb_Grasp.morphValue = 0f; personInfo.Right_Thumb_in_out.morphValue = 0f; personInfo.Left_Fingers_Grasp.morphValue = 0f; personInfo.Left_Thumb_Bend.morphValue = 0f; personInfo.Left_Thumb_Grasp.morphValue = 0f; personInfo.Left_Thumb_in_out.morphValue = 0f; personInfo.Pussy_Fingers_R.morphValue = 0f; personInfo.Pussy_Fingers_L.morphValue = 0f; personInfo.Pussy_Fingers_Bend_R.morphValue = 0f; personInfo.Pussy_Fingers_Bend_L.morphValue = 0f; personInfo.Pussy_Fingers2_R.morphValue = 0f; personInfo.Pussy_Fingers2_L.morphValue = 0f; personInfo.Pussy_Fingers2_Bend_R.morphValue = 0f; personInfo.Pussy_Fingers2_Bend_L.morphValue = 0f; personInfo.Mouth_Wide_Open.morphValue = 0f; personInfo.BJ_DX_Mouth_Open_Shape.morphValue = 0f; personInfo.BJ_DX_Mouth_Suck_Shape_1.morphValue = 0f; personInfo.BJ_DX_Mouth_Suck_Shape_2.morphValue = 0f; personInfo.BJ_DX_Kiss_2.morphValue = 0f; personInfo.BJ_DX_Mouth_Corner_Depth_L.morphValue = 0f; personInfo.BJ_DX_Mouth_Corner_Depth_R.morphValue = 0f; personInfo.BJ_DX_Cheek_Corner_Depth_L.morphValue = 0f; personInfo.BJ_DX_Cheek_Corner_Depth_R.morphValue = 0f; personInfo.BJ_DX_Mouth_Corner_Height_L.morphValue = 0f; personInfo.BJ_DX_Mouth_Corner_Height_R.morphValue = 0f; personInfo.BJ_DX_Cheek_Corner_Width_L.morphValue = 0f; personInfo.BJ_DX_Cheek_Corner_Width_R.morphValue = 0f; personInfo.Tongue_In_Out.morphValue = 0f; personInfo.Tongue_Side_Side.morphValue = 0f; personInfo.Tongue_Bend.morphValue = 0f; personInfo.Tongue_Narrow_Wide.morphValue = 0f; personInfo.Tongue_Thickness.morphValue = 0f; if (personInfo.IsFemale) { personInfo.Lips_Close.morphValue = 0f; personInfo.Lip_Bottom_UP.morphValue = 0f; } } } } public void OnDisable() { try { cleanup(); //SuperController.LogMessage($"{nameof(DiviningLipsAndHands)} disabled"); } catch (Exception e) { SuperController.LogError($"{nameof(DiviningLipsAndHands)}.{nameof(OnDisable)}: {e}"); } } public void OnDestroy() { try { cleanup(); //SuperController.LogMessage($"{nameof(DiviningLipsAndHands)} destroyed"); } catch (Exception e) { SuperController.LogError($"{nameof(DiviningLipsAndHands)}.{nameof(OnDestroy)}: {e}"); } } public Vector3 GetOffset(string targetType) { Vector3 offset = new Vector3(0f, 0f, 0f); if (targetType == "rHand") { offset = new Vector3(_handOffsetXJSON.val, _handOffsetYJSON.val, _handOffsetZJSON.val); } else if (targetType == "lHand") { // swap x axis for left hand offset = new Vector3(-_handOffsetXJSON.val, _handOffsetYJSON.val, _handOffsetZJSON.val); } else if (targetType == "Mouth") { offset = new Vector3( _mouthOffsetXJSON.val, _mouthOffsetYJSON.val, _mouthOffsetZJSON.val); } else if (targetType == "Vagina") { offset = new Vector3( _VaginaOffsetXJSON.val, _VaginaOffsetYJSON.val, _VaginaOffsetZJSON.val); } return offset * 0.01f; // cm to m } public float DistanceNearsetBetweenLine(Vector3 target, Vector3 Postion1, Vector3 Postion2) { //ensure dildo has a direction Postion1 += new Vector3(0f,0.0001f,0.0f); yzDirection = (Postion2 - Postion1).normalized; // the direction of the line between Y and Z xToY = Postion1 - target; // vector from X to Y projection = Vector3.ProjectOnPlane(xToY, yzDirection); // projection of xToY onto the plane perpendicular to yzDirection return projection.magnitude; // the distance between X and the nearest point on the line } public string CheckAlignment(Transform firstTransform, Transform secondTransform) { rotationDifference = Quaternion.Inverse(firstTransform.rotation) * (secondTransform.rotation * Quaternion.Euler(0, 90, 90)); eulerDifference = rotationDifference.eulerAngles; angleDifference = eulerDifference.x; if (angleDifference > 180f) angleDifference -= 360f; if (Mathf.Abs(angleDifference) < alignmentThreshold || Mathf.Abs(angleDifference - 180f) < alignmentThreshold) { return (_vagFingeringChooser.val == "F1 Horizontal F2 Vertical" ? "vertical" : "horizontal"); } else { return (_vagFingeringChooser.val == "F1 Horizontal F2 Vertical" ? "horizontal" : "vertical"); } } public float MorphAmount(float potentialTargetDistance, float Range, float changeRange ) { potentialTargetAmount = Mathf.Abs(potentialTargetDistance - Range); if(potentialTargetAmount < changeRange) { return Mathf.Lerp(0f, 1f, Mathf.Clamp01(Mathf.Abs((potentialTargetAmount - changeRange) / changeRange))); } else { return 0f; } } public void DoTimerTicks() { //BJ if (Mathf.PingPong(BJ_timer, 1f) < 0.1f) { // Pause for the specified duration BJ_DX_Mouth_Suck_Shape_2_speed = UnityEngine.Random.Range(0.5f, _BJ_DX_Mouth_Suck_Shape_2_speedJSON.val); } BJ_timer += Time.deltaTime * BJ_DX_Mouth_Suck_Shape_2_speed; BJ_lerpValue = Mathf.Lerp(0.0f, BJ_DX_Mouth_Suck_Shape_2_minmaxJSON.val + nipple_suck_animation_offset, Mathf.PingPong(BJ_timer, 1f)); //Tongue if (Mathf.PingPong(Tongue_timer2, 10f) < 0.1f) { // Pause for the specified duration isMovingForward = UnityEngine.Random.value < forwardBackwardRatio; if (isMovingForward) { Tongue_speed = UnityEngine.Random.Range(2.0f, _cock_lick_speedJSON.val); Tongue_speed2 = UnityEngine.Random.Range(2.0f, _cock_lick_speedJSON.val); } else { Tongue_speed = -UnityEngine.Random.Range(2.0f, _cock_lick_speedJSON.val); Tongue_speed2 = UnityEngine.Random.Range(2.0f, _cock_lick_speedJSON.val); } } Tongue_timer += Time.deltaTime * Tongue_speed; Tongue_timer2 += Time.deltaTime * Tongue_speed2; // Calculate the position on the circle using x and y values Tongue_lerpValue = Mathf.Cos(Tongue_timer); Tongue_lerpValue2 = Mathf.Sin(Tongue_timer); //Adjust Tongue_lerpValue2 as proportions not the same proportion = Mathf.InverseLerp(-1f, 1f, Tongue_lerpValue2); Tongue_lerpValue2 = Mathf.Lerp(-0.4f, 0.4f, proportion); if (Mathf.PingPong(Tongue_timer2, 10f) < 0.1f) { // Pause for the specified duration isMovingForward = UnityEngine.Random.value < forwardBackwardRatio; if (isMovingForward) { Kissing_speed = UnityEngine.Random.Range(2.0f, _kiss_tongue_bend_speedJSON.val); Kissing_speed2 = UnityEngine.Random.Range(2.0f, _kiss_tongue_bend_speedJSON.val); } else { Kissing_speed = -UnityEngine.Random.Range(2.0f, _kiss_tongue_bend_speedJSON.val); Kissing_speed2 = UnityEngine.Random.Range(2.0f, _kiss_tongue_bend_speedJSON.val); } } Kissing_timer += Time.deltaTime * Tongue_speed; // Calculate the position on the circle using x and y values Kissing_lerpValue = Mathf.Cos(Kissing_timer); Kissing_lerpValue2 = Mathf.Sin(Kissing_timer); //Adjust Tongue_lerpValue2 as proportions not the same proportion = Mathf.InverseLerp(-1f, 1f, Kissing_lerpValue2); Kissing_lerpValue2 = Mathf.Lerp(-0.4f, 0.4f, proportion); //Tongue in out if (Mathf.PingPong(Tongue_inout_timer, 1f) < 0.1f) { // Pause for the specified duration Tongue_inout_speed = UnityEngine.Random.Range(0.5f, _BJ_tongue_in_out_speedJSON.val); } Tongue_inout_timer += Time.deltaTime * Tongue_inout_speed; Tongue_inout_lerpValue = Mathf.Lerp(0.5f, Tongue_in_out_minmaxJSON.val, Mathf.PingPong(Tongue_inout_timer, 1f)); //fingers if (Mathf.PingPong(fingers_timer, 0.5f) < 0.1f) { // Pause for the specified duration fingers_speed = UnityEngine.Random.Range(0.5f, _vag_fingers_speedJSON.val); } fingers_timer += Time.deltaTime * fingers_speed; fingers_lerpValue = Mathf.Lerp(0f, Fingering_minmaxJSON.val, Mathf.PingPong(fingers_timer, 1f))*2; } // FixedUpdate is called with each physics simulation frame by Unity void FixedUpdate() { try { foreach (PersonInfo personInfo in ListOfPersonAtoms) { if (personInfo.PersonAtom.type == "Person" && personInfo.PersonAtom.on) { potentialRHandTargetDistance = _minTargetDistanceJSON.val * 0.01f; potentialLHandTargetDistance = _minTargetDistanceJSON.val * 0.01f; potentialMouthTargetDistance = _minTargetDistanceJSON.val * 0.01f; rHandTargetType = "none"; lHandTargetType = "none"; foreach (PersonInfo potentialTarget in ListOfPersonAtoms) { if ((potentialTarget.PersonAtom.type == "Person" || potentialTarget.PersonAtom.type == "Dildo") && potentialTarget.PersonAtom.on) { //Penis targets if (_handGraspAnyGenderEnabledJSON.val || !potentialTarget.IsFemale || potentialTarget.PersonAtom.type == "Dildo") { if(potentialTarget.PersonAtom.type == "Dildo") { potentialRHandTarget = potentialTarget.PersonAtom.freeControllers.First(fc => fc.name == "control"); potentialRHandTIPTarget = potentialTarget.PersonAtom.freeControllers.First(fc => fc.name == "control"); potentialLHandTarget = potentialTarget.PersonAtom.freeControllers.First(fc => fc.name == "control"); potentialLHandTIPTarget = potentialTarget.PersonAtom.freeControllers.First(fc => fc.name == "control"); potentialMouthTarget = potentialTarget.PersonAtom.freeControllers.First(fc => fc.name == "control"); } else { potentialRHandTarget = potentialTarget.PersonAtom.freeControllers.First(fc => fc.name == "penisMidControl"); potentialRHandTIPTarget = potentialTarget.PersonAtom.freeControllers.First(fc => fc.name == "penisTipControl"); potentialLHandTarget = potentialTarget.PersonAtom.freeControllers.First(fc => fc.name == "penisMidControl"); potentialLHandTIPTarget = potentialTarget.PersonAtom.freeControllers.First(fc => fc.name == "penisTipControl"); potentialMouthTarget = potentialTarget.PersonAtom.freeControllers.First(fc => fc.name == "penisMidControl"); } if (_handGraspEnabledJSON.val) { //RIGHT HAND & LEFT HAND _tmpPotentialDistance = DistanceNearsetBetweenLine(personInfo.atomRHand.transform.TransformPoint(GetOffset("rHand")), potentialRHandTarget.transform.position, potentialRHandTIPTarget.transform.position); _tmpPotentialDistance2 = DistanceNearsetBetweenLine(personInfo.atomLHand.transform.TransformPoint(GetOffset("lHand")), potentialLHandTarget.transform.position, potentialLHandTIPTarget.transform.position); if (_tmpPotentialDistance < potentialRHandTargetDistance && (potentialRHandTarget.transform.position - personInfo.atomRHand.transform.TransformPoint(GetOffset("rHand"))).magnitude < (_minTargetDistanceJSON.val * 0.01f)) { tmp_object_offset=(potentialTarget.PersonAtom.type == "Dildo" ? DildoOffsetJSON.val : 0f); potentialRHandTargetDistance = _tmpPotentialDistance + tmp_object_offset; rHandTargetType = "penis"; } if (_tmpPotentialDistance2 < potentialLHandTargetDistance && (potentialLHandTarget.transform.position - personInfo.atomLHand.transform.TransformPoint(GetOffset("lHand"))).magnitude < (_minTargetDistanceJSON.val * 0.01f)) { tmp_object_offset=(potentialTarget.PersonAtom.type == "Dildo" ? DildoOffsetJSON.val : 0f); potentialLHandTargetDistance = _tmpPotentialDistance2 + tmp_object_offset; lHandTargetType = "penis"; } } if (_lipsSuckEnabledJSON.val || _lips2ndAnimationEnabledJSON.val || _TonguePlayEnabledJSON.val) { //MOUTH _tmpPotentialDistance=(potentialMouthTarget.transform.position - personInfo.atomMouth.transform.TransformPoint(GetOffset("Mouth"))).magnitude; if (_tmpPotentialDistance < potentialMouthTargetDistance) { MouthTargetType="penis"; tmp_object_offset=(potentialTarget.PersonAtom.type == "Dildo" ? DildoOffsetJSON.val : 0f); potentialMouthTargetDistance = _tmpPotentialDistance + tmp_object_offset; } } } if (potentialTarget.IsFemale) { //mouth lick nipple potentialMouthTarget = potentialTarget.PersonAtom.freeControllers.First(fc => fc.name == "rNippleControl"); _tmpPotentialDistance=(potentialMouthTarget.transform.position - personInfo.atomMouth.transform.TransformPoint(GetOffset("Mouth"))).magnitude; if (_tmpPotentialDistance < potentialMouthTargetDistance) { potentialMouthTargetDistance = _tmpPotentialDistance; MouthTargetType="nipple"; } potentialMouthTarget = potentialTarget.PersonAtom.freeControllers.First(fc => fc.name == "lNippleControl"); _tmpPotentialDistance=(potentialMouthTarget.transform.position - personInfo.atomMouth.transform.TransformPoint(GetOffset("Mouth"))).magnitude; if (_tmpPotentialDistance < potentialMouthTargetDistance) { potentialMouthTargetDistance = _tmpPotentialDistance; MouthTargetType="nipple"; } potentialMouthTarget = potentialTarget.PersonAtom.rigidbodies.First(rb => rb.name == "VaginaTrigger"); _tmpPotentialDistance=(potentialMouthTarget.transform.position - personInfo.atomMouth.transform.TransformPoint(GetOffset("Vagina"))).magnitude; if (_tmpPotentialDistance < potentialMouthTargetDistance) { potentialMouthTargetDistance = _tmpPotentialDistance; MouthTargetType="vagina"; } //hand grab nipple potentialRHandTarget = potentialTarget.PersonAtom.freeControllers.First(fc => fc.name == "rNippleControl"); _tmpPotentialDistance=(potentialRHandTarget.transform.position - personInfo.atomRHand.transform.TransformPoint(GetOffset("rHand"))).magnitude; if (_tmpPotentialDistance < potentialRHandTargetDistance) { potentialRHandTargetDistance = _tmpPotentialDistance; rHandTargetType="nipple"; } potentialRHandTarget = potentialTarget.PersonAtom.freeControllers.First(fc => fc.name == "lNippleControl"); _tmpPotentialDistance=(potentialRHandTarget.transform.position - personInfo.atomRHand.transform.TransformPoint(GetOffset("rHand"))).magnitude; if (_tmpPotentialDistance < potentialRHandTargetDistance) { potentialRHandTargetDistance = _tmpPotentialDistance; rHandTargetType="nipple"; } potentialLHandTarget = potentialTarget.PersonAtom.freeControllers.First(fc => fc.name == "rNippleControl"); _tmpPotentialDistance=(potentialLHandTarget.transform.position - personInfo.atomLHand.transform.TransformPoint(GetOffset("lHand"))).magnitude; if (_tmpPotentialDistance < potentialLHandTargetDistance) { potentialLHandTargetDistance = _tmpPotentialDistance; lHandTargetType="nipple"; } potentialLHandTarget = potentialTarget.PersonAtom.freeControllers.First(fc => fc.name == "lNippleControl"); _tmpPotentialDistance=(potentialLHandTarget.transform.position - personInfo.atomLHand.transform.TransformPoint(GetOffset("lHand"))).magnitude; if (_tmpPotentialDistance < potentialLHandTargetDistance) { potentialLHandTargetDistance = _tmpPotentialDistance; lHandTargetType="nipple"; } if(_vagFingeringChooser.val != "Off") { potentialRHandTarget = potentialTarget.PersonAtom.rigidbodies.First(rb => rb.name == "VaginaTrigger"); potentialLHandTarget = potentialTarget.PersonAtom.rigidbodies.First(rb => rb.name == "VaginaTrigger"); _tmpPotentialDistance = (potentialRHandTarget.transform.position - personInfo.atomRHand.transform.TransformPoint(GetOffset("rHand"))).magnitude; _tmpPotentialDistance2 = (potentialLHandTarget.transform.position - personInfo.atomLHand.transform.TransformPoint(GetOffset("lHand"))).magnitude; if (_tmpPotentialDistance < potentialRHandTargetDistance && _tmpPotentialDistance < _tmpPotentialDistance2 && IsTargetInCylinder(personInfo.atomRHand.transform, potentialRHandTarget.transform)) { potentialRHandTargetDistance = _tmpPotentialDistance; if(_vagFingeringChooser.val == "Fingering Morph 1") { rHandTargetType="vagina_vertical"; }else if (_vagFingeringChooser.val == "Fingering Morph 2") { rHandTargetType="vagina_horizontal"; }else{ rHandTargetType="vagina_" + CheckAlignment(personInfo.atomRHand.transform, potentialRHandTarget.transform); } } else if (_tmpPotentialDistance2 < potentialLHandTargetDistance && IsTargetInCylinder(personInfo.atomLHand.transform, potentialLHandTarget.transform)) { potentialLHandTargetDistance = _tmpPotentialDistance2; if(_vagFingeringChooser.val == "Fingering Morph 1") { lHandTargetType="vagina_vertical"; }else if (_vagFingeringChooser.val == "Fingering Morph 2") { lHandTargetType="vagina_horizontal"; }else{ lHandTargetType="vagina_" + CheckAlignment(personInfo.atomLHand.transform, potentialLHandTarget.transform); } } } } if (potentialTarget.PersonAtom.type == "Person" && potentialTarget.PersonAtom != personInfo.PersonAtom) { _tmpPotentialDistance=(potentialTarget.atomMouth.transform.TransformPoint(GetOffset("Vagina")) - personInfo.atomMouth.transform.TransformPoint(GetOffset("Vagina"))).magnitude; if (_tmpPotentialDistance < potentialMouthTargetDistance) { potentialMouthTargetDistance = _tmpPotentialDistance; MouthTargetType="mouth"; } _tmpPotentialDistance=(personInfo.atomRHand.transform.TransformPoint(GetOffset("rHand")) - potentialTarget.atomRThigh.transform.position).magnitude; if (_tmpPotentialDistance < potentialRHandTargetDistance) { potentialRHandTargetDistance = _tmpPotentialDistance; rHandTargetType="hip"; } _tmpPotentialDistance=(personInfo.atomRHand.transform.TransformPoint(GetOffset("rHand")) - potentialTarget.atomLThigh.transform.position).magnitude; if (_tmpPotentialDistance < potentialRHandTargetDistance) { potentialRHandTargetDistance = _tmpPotentialDistance; rHandTargetType="hip"; } _tmpPotentialDistance=(personInfo.atomLHand.transform.TransformPoint(GetOffset("lHand")) - potentialTarget.atomRThigh.transform.position).magnitude; if (_tmpPotentialDistance < potentialLHandTargetDistance) { potentialLHandTargetDistance = _tmpPotentialDistance; lHandTargetType="hip"; } _tmpPotentialDistance=(personInfo.atomLHand.transform.TransformPoint(GetOffset("lHand")) - potentialTarget.atomLThigh.transform.position).magnitude; if (_tmpPotentialDistance < potentialLHandTargetDistance) { potentialLHandTargetDistance = _tmpPotentialDistance; lHandTargetType="hip"; } } } } if(_disableFingerControlPossessJSON.val) { if (potentialRHandTargetDistance < (_minTargetDistanceJSON.val * 0.01f)) { personInfo.PersonAtom.GetStorableByID("RightHandControl").GetBoolJSONParam("allowPossessFingerControl").val=((rHandTargetType=="nipple" || rHandTargetType=="hip") ? _enablePossessTitGrabJSON.val : false); } else { personInfo.PersonAtom.GetStorableByID("RightHandControl").GetBoolJSONParam("allowPossessFingerControl").val=true; } if(potentialLHandTargetDistance < (_minTargetDistanceJSON.val * 0.01f)) { personInfo.PersonAtom.GetStorableByID("LeftHandControl").GetBoolJSONParam("allowPossessFingerControl").val=((lHandTargetType=="nipple" || lHandTargetType=="hip") ? _enablePossessTitGrabJSON.val : false); } else { personInfo.PersonAtom.GetStorableByID("LeftHandControl").GetBoolJSONParam("allowPossessFingerControl").val=true; } } js = personInfo.PersonAtom.GetStorableByID("geometry"); dcs = js as DAZCharacterSelector; morphUI = dcs.morphsControlUI; //Tick all Lerps forwards DoTimerTicks(); //Penis Grab if (_handGraspEnabledJSON.val) { hand_grasp_a = _handGraspRangeJSON.val - _morpheChangeRangeJSON.val; hand_grasp_b = _handGraspRangeJSON.val + _morpheChangeRangeJSON.val; thumb_grasp_a = _thumbGraspRangeJSON.val - _morpheChangeRangeJSON.val; thumb_grasp_b = _thumbGraspRangeJSON.val + _morpheChangeRangeJSON.val; hand_grasp_start=0f; hand_grasp_end=-1.0f; thumb_bend_a = _thumbBendRangeJSON.val - (_morpheChangeRangeJSON.val); thumb_bend_b = _thumbBendRangeJSON.val + (_morpheChangeRangeJSON.val); thumb_bend_start=-1f; thumb_bend_end=0f; if (potentialRHandTargetDistance < (_minTargetDistanceJSON.val * 0.01f) && (rHandTargetType == "penis" || rHandTargetType == "nipple")) { hand_grasp_amount = (potentialRHandTargetDistance-hand_grasp_a)/(hand_grasp_b-hand_grasp_a) * (hand_grasp_end-hand_grasp_start) + hand_grasp_start; thumb_grasp_amount = (potentialRHandTargetDistance-thumb_grasp_a)/(thumb_grasp_b-thumb_grasp_a) * (hand_grasp_end-hand_grasp_start) + hand_grasp_start; personInfo.Pussy_Fingers_R.morphValue = 0f; personInfo.Pussy_Fingers_Bend_R.morphValue = 0f; personInfo.Pussy_Fingers2_R.morphValue = 0f; personInfo.Pussy_Fingers2_Bend_R.morphValue = 0f; if ( rHandTargetType == "penis" ) { personInfo.Right_Fingers_Grasp.morphValue = Mathf.Clamp(hand_grasp_amount, 0f, _hand_grasp_amountJSON.val); if(potentialRHandTargetDistance-_thumbBendRangeJSON.val < 0) { potentialABSRHandTargetDistance = Mathf.Abs(potentialRHandTargetDistance-_thumbBendRangeJSON.val) * 4.0f; }else { potentialABSRHandTargetDistance = Mathf.Abs(potentialRHandTargetDistance-_thumbBendRangeJSON.val) * 1.5f; } thumb_bend_amount = (potentialABSRHandTargetDistance-thumb_bend_a)/(thumb_bend_b-thumb_bend_a) * (thumb_bend_end-thumb_bend_start) + thumb_bend_start; personInfo.Right_Thumb_Bend.morphValue = Mathf.Clamp(thumb_bend_amount, -_thumb_Bend_amountJSON.val, 0f); personInfo.Right_Thumb_Grasp.morphValue = Mathf.Clamp(thumb_bend_amount, -_thumb_Bend_amountJSON.val, 0f); personInfo.Right_Thumb_in_out.morphValue = Mathf.Clamp(-thumb_bend_amount, 0f, 1f); } else { personInfo.Right_Fingers_Grasp.morphValue = Mathf.Clamp(hand_grasp_amount, 0f, _hand_tit_grasp_amountJSON.val); personInfo.Right_Thumb_Bend.morphValue = 0f; personInfo.Right_Thumb_Grasp.morphValue = 0f; personInfo.Right_Thumb_in_out.morphValue = 0f; } } if (potentialLHandTargetDistance < (_minTargetDistanceJSON.val * 0.01f) && (lHandTargetType == "penis" || lHandTargetType == "nipple")) { hand_grasp_amount = (potentialLHandTargetDistance-hand_grasp_a)/(hand_grasp_b-hand_grasp_a) * (hand_grasp_end-hand_grasp_start) + hand_grasp_start; thumb_grasp_amount = (potentialLHandTargetDistance-thumb_grasp_a)/(thumb_grasp_b-thumb_grasp_a) * (hand_grasp_end-hand_grasp_start) + hand_grasp_start; personInfo.Pussy_Fingers_L.morphValue = 0f; personInfo.Pussy_Fingers_Bend_L.morphValue = 0f; personInfo.Pussy_Fingers2_L.morphValue = 0f; personInfo.Pussy_Fingers2_Bend_L.morphValue = 0f; if ( lHandTargetType == "penis" ) { personInfo.Left_Fingers_Grasp.morphValue = Mathf.Clamp(hand_grasp_amount, 0f, _hand_grasp_amountJSON.val); if(potentialLHandTargetDistance-_thumbBendRangeJSON.val < 0) { potentialABSLHandTargetDistance = Mathf.Abs(potentialLHandTargetDistance-_thumbBendRangeJSON.val) * 4.0f; }else { potentialABSLHandTargetDistance = Mathf.Abs(potentialLHandTargetDistance-_thumbBendRangeJSON.val) * 1.5f; } thumb_bend_amount = (potentialABSLHandTargetDistance-thumb_bend_a)/(thumb_bend_b-thumb_bend_a) * (thumb_bend_end-thumb_bend_start) + thumb_bend_start; personInfo.Left_Thumb_Bend.morphValue = Mathf.Clamp(thumb_bend_amount, -_thumb_Bend_amountJSON.val, 0f); personInfo.Left_Thumb_Grasp.morphValue = Mathf.Clamp(thumb_bend_amount, -_thumb_Bend_amountJSON.val, 0f); personInfo.Left_Thumb_in_out.morphValue = Mathf.Clamp(-thumb_bend_amount, 0, 1f); } else { personInfo.Left_Fingers_Grasp.morphValue = Mathf.Clamp(hand_grasp_amount, 0f, _hand_tit_grasp_amountJSON.val); personInfo.Left_Thumb_Bend.morphValue = 0f; personInfo.Left_Thumb_Grasp.morphValue = 0f; personInfo.Left_Thumb_in_out.morphValue = 0f; } } } //Fingering Vagina if (_vagFingeringChooser.val != "Off") { hand_grasp_a = _vagHandRangeJSON.val - _morpheChangeRangeJSON.val; hand_grasp_b = _vagHandRangeJSON.val + _morpheChangeRangeJSON.val; thumb_grasp_a = _vagFingeringRangeJSON.val - _morpheChangeRangeJSON.val; thumb_grasp_b = _vagFingeringRangeJSON.val + _morpheChangeRangeJSON.val; hand_grasp_start=0f; hand_grasp_end=-1.0f; if (potentialRHandTargetDistance < (_minTargetDistanceJSON.val * 0.01f) && rHandTargetType == "vagina_vertical") { hand_grasp_amount = (potentialRHandTargetDistance-hand_grasp_a)/(hand_grasp_b-hand_grasp_a) * (hand_grasp_end-hand_grasp_start) + hand_grasp_start; thumb_grasp_amount = (potentialRHandTargetDistance-thumb_grasp_a)/(thumb_grasp_b-thumb_grasp_a) * (hand_grasp_end-hand_grasp_start) + hand_grasp_start; personInfo.Pussy_Fingers_R.morphValue = Mathf.Clamp(hand_grasp_amount, 0f, _vag_fingers_amountJSON.val); personInfo.Pussy_Fingers_Bend_R.morphValue = Mathf.Clamp((fingers_lerpValue * thumb_grasp_amount), 0.0f, Fingering_minmaxJSON.val); personInfo.Pussy_Fingers2_R.morphValue = 0f; personInfo.Pussy_Fingers2_Bend_R.morphValue = 0f; personInfo.Right_Fingers_Grasp.morphValue = 0f; personInfo.Right_Thumb_Bend.morphValue = 0f; personInfo.Right_Thumb_Grasp.morphValue = 0f; } if (potentialRHandTargetDistance < (_minTargetDistanceJSON.val * 0.01f) && rHandTargetType == "vagina_horizontal") { hand_grasp_amount = (potentialRHandTargetDistance-hand_grasp_a)/(hand_grasp_b-hand_grasp_a) * (hand_grasp_end-hand_grasp_start) + hand_grasp_start; thumb_grasp_amount = (potentialRHandTargetDistance-thumb_grasp_a)/(thumb_grasp_b-thumb_grasp_a) * (hand_grasp_end-hand_grasp_start) + hand_grasp_start; personInfo.Pussy_Fingers2_R.morphValue = Mathf.Clamp(hand_grasp_amount, 0f, _vag_fingers_amountJSON.val); personInfo.Pussy_Fingers2_Bend_R.morphValue = Mathf.Clamp((fingers_lerpValue * thumb_grasp_amount), 0.0f, Fingering_minmaxJSON.val); personInfo.Pussy_Fingers_R.morphValue = 0f; personInfo.Pussy_Fingers_Bend_R.morphValue = 0f; personInfo.Right_Fingers_Grasp.morphValue = 0f; personInfo.Right_Thumb_Bend.morphValue = 0f; personInfo.Right_Thumb_Grasp.morphValue = 0f; } if (potentialLHandTargetDistance < (_minTargetDistanceJSON.val * 0.01f) && lHandTargetType == "vagina_vertical") { hand_grasp_amount = (potentialLHandTargetDistance-hand_grasp_a)/(hand_grasp_b-hand_grasp_a) * (hand_grasp_end-hand_grasp_start) + hand_grasp_start; thumb_grasp_amount = (potentialLHandTargetDistance-thumb_grasp_a)/(thumb_grasp_b-thumb_grasp_a) * (hand_grasp_end-hand_grasp_start) + hand_grasp_start; personInfo.Pussy_Fingers_L.morphValue = Mathf.Clamp(hand_grasp_amount, 0f, _vag_fingers_amountJSON.val); personInfo.Pussy_Fingers_Bend_L.morphValue = Mathf.Clamp((fingers_lerpValue * thumb_grasp_amount), 0.0f, Fingering_minmaxJSON.val); personInfo.Pussy_Fingers2_L.morphValue = 0f; personInfo.Pussy_Fingers2_Bend_L.morphValue = 0f; personInfo.Left_Fingers_Grasp.morphValue = 0f; personInfo.Left_Thumb_Bend.morphValue = 0f; personInfo.Left_Thumb_Grasp.morphValue = 0f; } if (potentialLHandTargetDistance < (_minTargetDistanceJSON.val * 0.01f) && lHandTargetType == "vagina_horizontal") { hand_grasp_amount = (potentialLHandTargetDistance-hand_grasp_a)/(hand_grasp_b-hand_grasp_a) * (hand_grasp_end-hand_grasp_start) + hand_grasp_start; thumb_grasp_amount = (potentialLHandTargetDistance-thumb_grasp_a)/(thumb_grasp_b-thumb_grasp_a) * (hand_grasp_end-hand_grasp_start) + hand_grasp_start; personInfo.Pussy_Fingers2_L.morphValue = Mathf.Clamp(hand_grasp_amount, 0f, _vag_fingers_amountJSON.val); personInfo.Pussy_Fingers2_Bend_L.morphValue = Mathf.Clamp((fingers_lerpValue * thumb_grasp_amount), 0.0f, Fingering_minmaxJSON.val); personInfo.Pussy_Fingers_L.morphValue = 0f; personInfo.Pussy_Fingers_Bend_L.morphValue = 0f; personInfo.Left_Fingers_Grasp.morphValue = 0f; personInfo.Left_Thumb_Bend.morphValue = 0f; personInfo.Left_Thumb_Grasp.morphValue = 0f; } } if((rHandTargetType == "none" || rHandTargetType == "vagina_none" || rHandTargetType == "hip") && (_vagFingeringChooser.val == "Off" || _handGraspEnabledJSON.val)) { personInfo.Right_Fingers_Grasp.morphValue = 0f; personInfo.Pussy_Fingers_R.morphValue = 0f; personInfo.Pussy_Fingers_Bend_R.morphValue = 0f; personInfo.Pussy_Fingers2_R.morphValue = 0f; personInfo.Pussy_Fingers2_Bend_R.morphValue = 0f; personInfo.Right_Thumb_Bend.morphValue = 0f; personInfo.Right_Thumb_Grasp.morphValue = 0f; personInfo.Right_Thumb_in_out.morphValue = 0f; } if((lHandTargetType == "none" || lHandTargetType == "vagina_none" || lHandTargetType == "hip") && (_vagFingeringChooser.val == "Off" || _handGraspEnabledJSON.val)) { personInfo.Left_Fingers_Grasp.morphValue = 0f; personInfo.Pussy_Fingers_L.morphValue = 0f; personInfo.Pussy_Fingers_Bend_L.morphValue = 0f; personInfo.Pussy_Fingers2_L.morphValue = 0f; personInfo.Pussy_Fingers2_Bend_L.morphValue = 0f; personInfo.Left_Thumb_Bend.morphValue = 0f; personInfo.Left_Thumb_Grasp.morphValue = 0f; personInfo.Left_Thumb_in_out.morphValue = 0f; } //SuperController.LogMessage("MouthTargetType " + MouthTargetType); //Mouth if (potentialMouthTargetDistance < (_minTargetDistanceJSON.val * 0.01f)) { mouth_open_a = _mouthOpenRangeJSON.val - _morpheChangeRangeJSON.val; mouth_open_b = _mouthOpenRangeJSON.val + _morpheChangeRangeJSON.val; mouth_suck_a = _suckRangeJSON.val - _morpheChangeRangeJSON.val; mouth_suck_b = _suckRangeJSON.val + _morpheChangeRangeJSON.val; tongue_a = _tonguePenisLickRangeJSON.val - _morpheChangeRangeJSON.val; tongue_b = _tonguePenisLickRangeJSON.val + _morpheChangeRangeJSON.val; nipple_suck_animation_offset=0; if (MouthTargetType == "nipple") { nipple_suck_animation_offset=0.35f; mouth_open_a -= nipple_mouth_offset; mouth_open_b -= nipple_mouth_offset; mouth_suck_a -= nipple_suck_offset; mouth_suck_b -= nipple_suck_offset; } if (MouthTargetType == "mouth") { nipple_suck_animation_offset=0.35f; mouth_open_a -= mouth_mouth_offset; mouth_open_b -= mouth_mouth_offset; mouth_suck_a -= mouth_suck_offset; mouth_suck_b -= mouth_suck_offset; } if (MouthTargetType == "vagina") { nipple_suck_animation_offset=0.35f; mouth_open_a += vag_mouth_offset; mouth_open_b += vag_mouth_offset; mouth_suck_a += vag_suck_offset; mouth_suck_b += vag_suck_offset; } mouth_open_start=0f; mouth_open_end=-(BJ_DX_Mouth_Suck_Shape_1_AMOUNT_JSON.val > Mouth_Open_Wide_Amount_JSON.val ? BJ_DX_Mouth_Suck_Shape_1_AMOUNT_JSON.val : Mouth_Open_Wide_Amount_JSON.val);//BJ_DX_Mouth_Suck_Shape_1_AMOUNT_JSON.val; hand_grasp_amount = (potentialMouthTargetDistance-mouth_open_a)/(mouth_open_b-mouth_open_a) * (mouth_open_end-mouth_open_start) + mouth_open_start; mouth_amount = Mathf.Clamp((potentialMouthTargetDistance - mouth_suck_a)/(mouth_suck_b-mouth_suck_a) * (mouth_open_end-mouth_open_start) + mouth_open_start, 0.0f, 3.0f); if(_TongueLickRangePointEnabledJSON.val) { if (MouthTargetType == "penis" || MouthTargetType == "vagina") { tongue_amount = MorphAmount(potentialMouthTargetDistance, _tonguePenisLickRangeJSON.val, _morpheChangeRangeJSON.val); } else if (MouthTargetType == "nipple"){ tongue_amount = MorphAmount(potentialMouthTargetDistance, _tongueNippleLickRangeJSON.val, _morpheNippleChangeRangeJSON.val); } else { tongue_amount = MorphAmount(potentialMouthTargetDistance, _tongueMouthKissRangeJSON.val, _morpheNippleChangeRangeJSON.val); } }else{ tongue_amount = mouth_amount; } if (_lipsSuckEnabledJSON.val) { if (MouthTargetType != "vagina") { personInfo.Mouth_Wide_Open.morphValue = Mathf.Clamp(hand_grasp_amount, 0f, Mouth_Open_Wide_Amount_JSON.val); } if (MouthTargetType != "mouth") { personInfo.BJ_DX_Mouth_Open_Shape.morphValue = Mathf.Clamp(mouth_amount, 0f, BJ_DX_Mouth_Suck_Shape_1_AMOUNT_JSON.val); personInfo.BJ_DX_Mouth_Suck_Shape_1.morphValue = Mathf.Clamp(mouth_amount, 0f, BJ_DX_Mouth_Suck_Shape_1_AMOUNT_JSON.val); personInfo.BJ_DX_Mouth_Corner_Depth_L.morphValue = Mathf.Clamp(mouth_amount, 0f, BJ_DX_Mouth_Suck_Shape_1_AMOUNT_JSON.val); personInfo.BJ_DX_Mouth_Corner_Depth_R.morphValue = Mathf.Clamp(mouth_amount, 0f, BJ_DX_Mouth_Suck_Shape_1_AMOUNT_JSON.val); personInfo.BJ_DX_Cheek_Corner_Depth_L.morphValue = Mathf.Clamp(mouth_amount, 0f, BJ_DX_Mouth_Suck_Shape_1_AMOUNT_JSON.val); personInfo.BJ_DX_Cheek_Corner_Depth_R.morphValue = Mathf.Clamp(mouth_amount, 0f, BJ_DX_Mouth_Suck_Shape_1_AMOUNT_JSON.val); personInfo.BJ_DX_Mouth_Corner_Height_L.morphValue = Mathf.Clamp(mouth_amount, 0f, BJ_DX_Mouth_Suck_Shape_1_AMOUNT_JSON.val); personInfo.BJ_DX_Mouth_Corner_Height_R.morphValue = Mathf.Clamp(mouth_amount, 0f, BJ_DX_Mouth_Suck_Shape_1_AMOUNT_JSON.val); personInfo.BJ_DX_Cheek_Corner_Width_L.morphValue = Mathf.Clamp(mouth_amount*4, 0f, BJ_DX_Mouth_Suck_Shape_1_AMOUNT_JSON.val*4); personInfo.BJ_DX_Cheek_Corner_Width_R.morphValue = Mathf.Clamp(mouth_amount*4, 0f, BJ_DX_Mouth_Suck_Shape_1_AMOUNT_JSON.val*4); if (personInfo.IsFemale) { personInfo.Lips_Close.morphValue = Mathf.Clamp(-mouth_amount, lips_close_amountJSON.val, 0f); personInfo.Lip_Bottom_UP.morphValue = Mathf.Clamp(mouth_amount, 0f, Mathf.Abs(lips_close_amountJSON.val/2)); } } } //lips suck animation if (_lips2ndAnimationEnabledJSON.val) { personInfo.BJ_DX_Mouth_Suck_Shape_2.morphValue = Mathf.Clamp(BJ_lerpValue*mouth_amount, 0f, BJ_DX_Mouth_Suck_Shape_2_minmaxJSON.val + nipple_suck_animation_offset); personInfo.BJ_DX_Kiss_2.morphValue = Mathf.Clamp(BJ_lerpValue*mouth_amount, 0f, BJ_DX_Mouth_Suck_Shape_2_minmaxJSON.val + nipple_suck_animation_offset); } if (_TonguePlayEnabledJSON.val) { //cock lick if (MouthTargetType == "penis") { personInfo.Tongue_Side_Side.morphValue = Mathf.Clamp((Tongue_lerpValue)*tongue_amount, -Tongue_side_minmaxJSON.val, Tongue_side_minmaxJSON.val); personInfo.Tongue_Bend.morphValue = Mathf.Clamp((Tongue_lerpValue2 * tongue_amount), -0.4f, 0.4f); personInfo.Tongue_In_Out.morphValue = Mathf.Clamp(Tongue_inout_lerpValue * (-tongue_amount*2), -Tongue_in_out_minmaxJSON.val, 1); personInfo.Tongue_Thickness.morphValue = Mathf.Clamp(tongue_amount, 0f, 0.3f); personInfo.Tongue_Narrow_Wide.morphValue = Mathf.Clamp(-1+tongue_amount, -1f, 0.0f); } if (MouthTargetType == "nipple") { personInfo.Tongue_Side_Side.morphValue = Mathf.Clamp((Tongue_lerpValue)*tongue_amount, -Tongue_side_minmaxJSON.val, Tongue_side_minmaxJSON.val); personInfo.Tongue_Bend.morphValue = Mathf.Clamp((Tongue_lerpValue2 * tongue_amount), -0.4f, 0.4f); personInfo.Tongue_In_Out.morphValue = Mathf.Clamp(Tongue_inout_lerpValue * (-tongue_amount*2), -Tongue_in_out_minmaxJSON.val, 0); personInfo.Tongue_Thickness.morphValue = Mathf.Clamp(tongue_amount, 0f, 0.3f); personInfo.Tongue_Narrow_Wide.morphValue = Mathf.Clamp(-1+tongue_amount, -1f, 0.0f); } //Vingina lick if (MouthTargetType == "vagina") { //SuperController.LogMessage("Tongue_inout_lerpValue " + Tongue_inout_lerpValue + " tongue_amount " + tongue_amount); personInfo.Tongue_Side_Side.morphValue = Mathf.Clamp((Tongue_lerpValue)*tongue_amount, -Tongue_side_minmaxJSON.val/2, Tongue_side_minmaxJSON.val/2); personInfo.Tongue_Bend.morphValue = Mathf.Clamp((Tongue_lerpValue2 * tongue_amount), -0.8f, 0.8f); personInfo.Tongue_In_Out.morphValue = Mathf.Clamp(Tongue_inout_lerpValue * (-tongue_amount*2), -Tongue_in_out_minmaxJSON.val-1, 0); personInfo.Tongue_Thickness.morphValue = Mathf.Clamp(tongue_amount, 0f, 0.3f); personInfo.Tongue_Narrow_Wide.morphValue = Mathf.Clamp(-1+tongue_amount, -1f, 0.0f); } //Mouth Kiss if (MouthTargetType == "mouth") { personInfo.Tongue_Side_Side.morphValue = Mathf.Clamp((Kissing_lerpValue)*mouth_amount, -Tongue_side_minmaxJSON.val/4f, Tongue_side_minmaxJSON.val/4f); personInfo.Tongue_Bend.morphValue = Mathf.Clamp((Kissing_lerpValue2 * mouth_amount), -0.2f, 0.2f); personInfo.Tongue_In_Out.morphValue = Mathf.Clamp(Tongue_inout_lerpValue * (-tongue_amount*2), -Tongue_in_out_minmaxJSON.val, 0f); personInfo.Tongue_Thickness.morphValue = Mathf.Clamp(mouth_amount, 0f, 0.3f); personInfo.Tongue_Narrow_Wide.morphValue = Mathf.Clamp(-1+mouth_amount, -1f, 0.0f); } } } } } } catch (Exception e) { SuperController.LogError($"{nameof(DiviningLipsAndHands)}.{nameof(FixedUpdate)}: {e}"); } } } } // namespace ToumeiHitsuji end