void Awake() { _ik = this.GetComponentInChildren <IKManager>(); _animator = this.GetComponentInChildren <Animator>(); _callbackManager = this.GetComponentInChildren <AnimatorEventCallbackManager>(); _callbackManager.OnAnimationEventCalled += OnAnimationEventCalled; _animator.SetLayerWeight(2, 0f); GatherRenderers(); }
/// <summary> /// Gets the offset between the head target and the actual head bone. Avoids issues when using /// the Head transform for calculations. /// </summary> private Vector3 GetHeadTargetOffset() { Transform headReference = null; Transform headTarget = null; #pragma warning disable 618 VRIK vrik = gameObject.GetComponentInChildren <VRIK>(); IKManager ikManager = gameObject.GetComponentInChildren <IKManager>(); IKManagerAdvanced ikManagerAdvanced = gameObject.GetComponentInChildren <IKManagerAdvanced>(); #pragma warning restore 618 VRIKManager vrikManager = gameObject.GetComponentInChildren <VRIKManager>(); if (vrikManager) { if (!vrikManager.references_head) { vrikManager.AutoDetectReferences(); } headReference = vrikManager.references_head; headTarget = vrikManager.solver_spine_headTarget; } else if (vrik) { vrik.AutoDetectReferences(); headReference = vrik.references.head; if (ikManagerAdvanced) { headTarget = ikManagerAdvanced.HeadTarget; } else if (ikManager) { headTarget = ikManager.HeadTarget; } } if (!headReference) { Plugin.logger.Warn("Could not find head reference; height adjust may be broken"); return(Vector3.zero); } if (!headTarget) { Plugin.logger.Warn("Could not find head target; height adjust may be broken"); return(Vector3.zero); } return(headTarget.position - headReference.position); }
// Main Functions public void Init() { // components capsule = GetComponent <CapsuleCollider>(); rigidBody = GetComponent <Rigidbody>(); audioSource = GetComponent <AudioSource>(); rpg = GetComponent <RPGManager>(); rpg.Init(); // initialize bodies /*for (int i = 0; i < 2; i++) * { * bodies[i] = ObjectPool.Instance.GetObject(model + "(Clone)", transform); * }*/ // life body bodies[1] = ObjectPool.Instance.GetObject(model + "_L(Clone)", transform); //DisableRagdoll(bodies[1]); aem = bodies[1].AddComponent <AnimatorEventManager>(); aem.Init(this); animator = aem.animator; ikManager = bodies[1].AddComponent <IKManager>(); ikManager.Init(this); // dead body bodies[0] = ObjectPool.Instance.GetObject(model + "(Clone)", transform); dieScript = bodies[0].AddComponent <DieScript>(); dieScript.Init(); dieScript.states = this; deadBody = dieScript.gameObject; deadBody.SetActive(false); // item interaction and stuff PotionHandIdentifier potionHand = GetComponentInChildren <PotionHandIdentifier>(); if (potionHand != null) { this.potionHand = potionHand.transform; } pickUp.actionAnimationName = "Pick Up"; }
#pragma warning disable CS0618 private void ApplyIKManagerFields(VRIKManager vrikManager, IKManager ikManager) { vrikManager.solver_spine_headTarget = ikManager.HeadTarget; vrikManager.solver_leftArm_target = ikManager.LeftHandTarget; vrikManager.solver_rightArm_target = ikManager.RightHandTarget; if (!(ikManager is IKManagerAdvanced ikManagerAdvanced)) { return; } FieldInfo[] fieldInfos = typeof(IKManagerAdvanced).GetFields(BindingFlags.Instance | BindingFlags.Public); foreach (FieldInfo fieldInfo in fieldInfos) { string[] propertyName = fieldInfo.Name.Split('_'); var value = fieldInfo.GetValue(ikManagerAdvanced); if (propertyName.Length > 1) { if ("Spine" == propertyName[0]) { SetField(vrikManager, "solver_spine_" + propertyName[1], value); } else if ("LeftArm" == propertyName[0]) { SetField(vrikManager, "solver_leftArm_" + propertyName[1], value); } else if ("RightArm" == propertyName[0]) { SetField(vrikManager, "solver_rightArm_" + propertyName[1], value); } else if ("LeftLeg" == propertyName[0]) { SetField(vrikManager, "solver_leftLeg_" + propertyName[1], value); } else if ("RightLeg" == propertyName[0]) { SetField(vrikManager, "solver_rightLeg_" + propertyName[1], value); } else if ("Locomotion" == propertyName[0]) { SetField(vrikManager, "solver_locomotion_" + propertyName[1], value); } } } }
private void Awake() { /* * if(instance == null) * { * instance = this; * }else if(instance != this) * { * Destroy(gameObject); * } * DontDestroyOnLoad(gameObject); */ kawaraArray = new GameObject[kawaraNum]; ikManagerScript = GetComponent <IKManager>(); InitGame(); KawaraSetup(); }
IEnumerator CheckIKTargets(VRIK ik, IKManager ikman, GameObject avatar) { yield return(0); while (ik != null && ikman != null) { if (ik.solver.spine.headTarget == null || ik.solver.rightArm.target == null || ik.solver.leftArm.target == null) { avatar.transform.parent = space ?? transform; Plugin.Log("vrik values were null!"); ik.solver.spine.headTarget = head; //ikman.RightHandTarget = rightHand; ik.solver.rightArm.target = rightHand; //ikman.LeftHandTarget = leftHand; ik.solver.leftArm.target = leftHand; Plugin.Log("vrik values have been set!"); } yield return(new WaitForSecondsRealtime(1)); } Plugin.Log("vrik or ikman was null, quitting!"); }
#pragma warning disable CS0618 private void ApplyIKManagerFields(VRIKManager vrikManager, IKManager ikManager) { vrikManager.solver_spine_headTarget = ikManager.HeadTarget; vrikManager.solver_leftArm_target = ikManager.LeftHandTarget; vrikManager.solver_rightArm_target = ikManager.RightHandTarget; if (!(ikManager is IKManagerAdvanced ikManagerAdvanced)) { return; } vrikManager.solver_spine_pelvisTarget = ikManagerAdvanced.Spine_pelvisTarget; vrikManager.solver_spine_pelvisPositionWeight = ikManagerAdvanced.Spine_pelvisPositionWeight; vrikManager.solver_spine_pelvisRotationWeight = ikManagerAdvanced.Spine_pelvisRotationWeight; vrikManager.solver_spine_positionWeight = ikManagerAdvanced.Head_positionWeight; vrikManager.solver_spine_rotationWeight = ikManagerAdvanced.Head_rotationWeight; vrikManager.solver_spine_chestGoal = ikManagerAdvanced.Spine_chestGoal; vrikManager.solver_spine_chestGoalWeight = ikManagerAdvanced.Spine_chestGoalWeight; vrikManager.solver_spine_minHeadHeight = ikManagerAdvanced.Spine_minHeadHeight; vrikManager.solver_spine_bodyPosStiffness = ikManagerAdvanced.Spine_bodyPosStiffness; vrikManager.solver_spine_bodyRotStiffness = ikManagerAdvanced.Spine_bodyRotStiffness; vrikManager.solver_spine_neckStiffness = ikManagerAdvanced.Spine_neckStiffness; vrikManager.solver_spine_chestClampWeight = ikManagerAdvanced.Spine_chestClampWeight; vrikManager.solver_spine_headClampWeight = ikManagerAdvanced.Spine_headClampWeight; vrikManager.solver_spine_maintainPelvisPosition = ikManagerAdvanced.Spine_maintainPelvisPosition; vrikManager.solver_spine_maxRootAngle = ikManagerAdvanced.Spine_maxRootAngle; vrikManager.solver_leftArm_bendGoal = ikManagerAdvanced.LeftArm_bendGoal; vrikManager.solver_leftArm_positionWeight = ikManagerAdvanced.LeftArm_positionWeight; vrikManager.solver_leftArm_rotationWeight = ikManagerAdvanced.LeftArm_rotationWeight; vrikManager.solver_leftArm_shoulderRotationMode = ikManagerAdvanced.LeftArm_shoulderRotationMode; vrikManager.solver_leftArm_shoulderRotationWeight = ikManagerAdvanced.LeftArm_shoulderRotationWeight; vrikManager.solver_leftArm_bendGoalWeight = ikManagerAdvanced.LeftArm_bendGoalWeight; vrikManager.solver_leftArm_swivelOffset = ikManagerAdvanced.LeftArm_swivelOffset; vrikManager.solver_leftArm_wristToPalmAxis = ikManagerAdvanced.LeftArm_wristToPalmAxis; vrikManager.solver_leftArm_palmToThumbAxis = ikManagerAdvanced.LeftArm_palmToThumbAxis; vrikManager.solver_rightArm_bendGoal = ikManagerAdvanced.RightArm_bendGoal; vrikManager.solver_rightArm_positionWeight = ikManagerAdvanced.RightArm_positionWeight; vrikManager.solver_rightArm_rotationWeight = ikManagerAdvanced.RightArm_rotationWeight; vrikManager.solver_rightArm_shoulderRotationMode = ikManagerAdvanced.RightArm_shoulderRotationMode; vrikManager.solver_rightArm_shoulderRotationWeight = ikManagerAdvanced.RightArm_shoulderRotationWeight; vrikManager.solver_rightArm_bendGoalWeight = ikManagerAdvanced.RightArm_bendGoalWeight; vrikManager.solver_rightArm_swivelOffset = ikManagerAdvanced.RightArm_swivelOffset; vrikManager.solver_rightArm_wristToPalmAxis = ikManagerAdvanced.RightArm_wristToPalmAxis; vrikManager.solver_rightArm_palmToThumbAxis = ikManagerAdvanced.RightArm_palmToThumbAxis; vrikManager.solver_leftLeg_target = ikManagerAdvanced.LeftLeg_target; vrikManager.solver_leftLeg_positionWeight = ikManagerAdvanced.LeftLeg_positionWeight; vrikManager.solver_leftLeg_rotationWeight = ikManagerAdvanced.LeftLeg_rotationWeight; vrikManager.solver_leftLeg_bendGoal = ikManagerAdvanced.LeftLeg_bendGoal; vrikManager.solver_leftLeg_bendGoalWeight = ikManagerAdvanced.LeftLeg_bendGoalWeight; vrikManager.solver_leftLeg_swivelOffset = ikManagerAdvanced.LeftLeg_swivelOffset; vrikManager.solver_rightLeg_target = ikManagerAdvanced.RightLeg_target; vrikManager.solver_rightLeg_positionWeight = ikManagerAdvanced.RightLeg_positionWeight; vrikManager.solver_rightLeg_rotationWeight = ikManagerAdvanced.RightLeg_rotationWeight; vrikManager.solver_rightLeg_bendGoal = ikManagerAdvanced.RightLeg_bendGoal; vrikManager.solver_rightLeg_bendGoalWeight = ikManagerAdvanced.RightLeg_bendGoalWeight; vrikManager.solver_rightLeg_swivelOffset = ikManagerAdvanced.RightLeg_swivelOffset; vrikManager.solver_locomotion_weight = ikManagerAdvanced.Locomotion_weight; vrikManager.solver_locomotion_footDistance = ikManagerAdvanced.Locomotion_footDistance; vrikManager.solver_locomotion_stepThreshold = ikManagerAdvanced.Locomotion_stepThreshold; vrikManager.solver_locomotion_angleThreshold = ikManagerAdvanced.Locomotion_angleThreshold; vrikManager.solver_locomotion_comAngleMlp = ikManagerAdvanced.Locomotion_comAngleMlp; vrikManager.solver_locomotion_maxVelocity = ikManagerAdvanced.Locomotion_maxVelocity; vrikManager.solver_locomotion_velocityFactor = ikManagerAdvanced.Locomotion_velocityFactor; vrikManager.solver_locomotion_maxLegStretch = ikManagerAdvanced.Locomotion_maxLegStretch; vrikManager.solver_locomotion_rootSpeed = ikManagerAdvanced.Locomotion_rootSpeed; vrikManager.solver_locomotion_stepSpeed = ikManagerAdvanced.Locomotion_stepSpeed; vrikManager.solver_locomotion_stepHeight = ikManagerAdvanced.Locomotion_stepHeight; vrikManager.solver_locomotion_heelHeight = ikManagerAdvanced.Locomotion_heelHeight; vrikManager.solver_locomotion_relaxLegTwistMinAngle = ikManagerAdvanced.Locomotion_relaxLegTwistMinAngle; vrikManager.solver_locomotion_relaxLegTwistSpeed = ikManagerAdvanced.Locomotion_relaxLegTwistSpeed; vrikManager.solver_locomotion_stepInterpolation = ikManagerAdvanced.Locomotion_stepInterpolation; vrikManager.solver_locomotion_offset = ikManagerAdvanced.Locomotion_offset; vrikManager.solver_locomotion_onLeftFootstep = ikManagerAdvanced.Locomotion_onLeftFootstep; vrikManager.solver_locomotion_onRightFootstep = ikManagerAdvanced.Locomotion_onRightFootstep; }
internal void Construct(string fullPath, ILogger <AvatarPrefab> logger, IKHelper ikHelper, DiContainer container) { this.fullPath = fullPath ?? throw new ArgumentNullException(nameof(fullPath)); descriptor = GetComponent <AvatarDescriptor>() ?? throw new AvatarLoadException($"Avatar at '{fullPath}' does not have an AvatarDescriptor"); fileName = Path.GetFileName(fullPath); _logger = logger; _logger.name = descriptor.name; #pragma warning disable CS0618 VRIKManager vrikManager = GetComponentInChildren <VRIKManager>(); IKManager ikManager = GetComponentInChildren <IKManager>(); #pragma warning restore CS0618 // migrate IKManager/IKManagerAdvanced to VRIKManager if (ikManager) { if (!vrikManager) { vrikManager = container.InstantiateComponent <VRIKManager>(gameObject); } _logger.Warning("IKManager and IKManagerAdvanced are deprecated; please migrate to VRIKManager"); ApplyIKManagerFields(vrikManager, ikManager); Destroy(ikManager); } if (vrikManager) { if (!vrikManager.areReferencesFilled) { _logger.Warning($"References are not filled on '{vrikManager.name}'; detecting references automatically"); vrikManager.AutoDetectReferences(); } } // remove any existing VRIK instances foreach (VRIK existingVrik in GetComponentsInChildren <VRIK>()) { _logger.Warning($"Found VRIK on '{existingVrik.name}'; manually adding VRIK to an avatar is no longer needed, please remove it"); if (existingVrik && vrikManager && existingVrik.references.isFilled && !vrikManager.areReferencesFilled) { _logger.Warning($"Copying references from VRIK on '{existingVrik.name}'; this is deprecated behaviour and will be removed in a future release"); CopyReferencesFromExistingVrik(vrikManager, existingVrik.references); } Destroy(existingVrik); } if (vrikManager) { ikHelper.CreateOffsetTargetsIfMissing(vrikManager, transform); } head = transform.Find("Head"); leftHand = transform.Find("LeftHand"); rightHand = transform.Find("RightHand"); pelvis = transform.Find("Pelvis"); leftLeg = transform.Find("LeftLeg"); rightLeg = transform.Find("RightLeg"); if (vrikManager) { if (vrikManager.references_root != vrikManager.transform) { _logger.Warning("VRIKManager is not on the root reference transform; this may cause unexpected issues"); } CheckTargetWeight("Left Arm", leftHand, vrikManager.solver_leftArm_positionWeight, vrikManager.solver_leftArm_rotationWeight); CheckTargetWeight("Right Arm", rightHand, vrikManager.solver_rightArm_positionWeight, vrikManager.solver_rightArm_rotationWeight); CheckTargetWeight("Pelvis", pelvis, vrikManager.solver_spine_pelvisPositionWeight, vrikManager.solver_spine_pelvisRotationWeight); CheckTargetWeight("Left Leg", leftLeg, vrikManager.solver_leftLeg_positionWeight, vrikManager.solver_leftLeg_rotationWeight); CheckTargetWeight("Right Leg", rightLeg, vrikManager.solver_rightLeg_positionWeight, vrikManager.solver_rightLeg_rotationWeight); FixTrackingReferences(vrikManager); } if (transform.localPosition.sqrMagnitude > 0) { _logger.Warning("Avatar root position is not at origin; this may cause unexpected issues"); } var poseManager = GetComponentInChildren <PoseManager>(); isIKAvatar = vrikManager; supportsFingerTracking = poseManager && poseManager.isValid; eyeHeight = GetEyeHeight(); armSpan = GetArmSpan(vrikManager); #pragma warning disable CS0612, CS0618 loadedAvatar = new LoadedAvatar(this); #pragma warning restore CS0612, CS0618 }
internal LoadedAvatar(string fullPath, GameObject avatarGameObject, ILoggerProvider loggerProvider, DiContainer container) { this.fullPath = fullPath ?? throw new ArgumentNullException(nameof(fullPath)); prefab = avatarGameObject ? avatarGameObject : throw new ArgumentNullException(nameof(avatarGameObject)); descriptor = avatarGameObject.GetComponent <AvatarDescriptor>() ?? throw new AvatarLoadException($"Avatar at '{fullPath}' does not have an AvatarDescriptor"); fileName = Path.GetFileName(fullPath); prefab.name = $"LoadedAvatar({descriptor.name})"; _logger = loggerProvider.CreateLogger <LoadedAvatar>(descriptor.name); head = prefab.transform.Find("Head"); leftHand = prefab.transform.Find("LeftHand"); rightHand = prefab.transform.Find("RightHand"); pelvis = prefab.transform.Find("Pelvis"); leftLeg = prefab.transform.Find("LeftLeg"); rightLeg = prefab.transform.Find("RightLeg"); #pragma warning disable CS0618 VRIKManager vrikManager = prefab.GetComponentInChildren <VRIKManager>(); IKManager ikManager = prefab.GetComponentInChildren <IKManager>(); #pragma warning restore CS0618 // migrate IKManager/IKManagerAdvanced to VRIKManager if (ikManager) { if (!vrikManager) { vrikManager = container.InstantiateComponent <VRIKManager>(prefab); } _logger.Warning("IKManager and IKManagerAdvanced are deprecated; please migrate to VRIKManager"); ApplyIKManagerFields(vrikManager, ikManager); Object.Destroy(ikManager); } if (vrikManager) { if (!vrikManager.areReferencesFilled) { _logger.Warning($"References are not filled on '{vrikManager.name}'; detecting references automatically"); vrikManager.AutoDetectReferences(); } } // remove any existing VRIK instances foreach (VRIK existingVrik in prefab.GetComponentsInChildren <VRIK>()) { _logger.Warning($"Found VRIK on '{existingVrik.name}'; manually adding VRIK to an avatar is no longer needed, please remove it"); if (existingVrik && vrikManager && existingVrik.references.isFilled && !vrikManager.areReferencesFilled) { _logger.Warning($"Copying references from VRIK on '{existingVrik.name}'; this is deprecated behaviour and will be removed in a future release"); CopyReferencesFromExistingVrik(vrikManager, existingVrik.references); } Object.Destroy(existingVrik); } if (vrikManager) { if (vrikManager.references_root != vrikManager.transform) { _logger.Warning("VRIKManager is not on the root reference transform; this may cause unexpected issues"); } FixTrackingReferences(vrikManager); } if (prefab.transform.localPosition.sqrMagnitude > 0) { _logger.Warning("Avatar root position is not at origin; this may cause unexpected issues"); } var poseManager = prefab.GetComponentInChildren <PoseManager>(); isIKAvatar = vrikManager; supportsFullBodyTracking = pelvis || leftLeg || rightLeg; supportsFingerTracking = poseManager && poseManager.isValid; eyeHeight = GetEyeHeight(); armSpan = GetArmSpan(vrikManager); }
internal LoadedAvatar(string fullPath, GameObject avatarGameObject, ILoggerProvider loggerProvider) { this.fullPath = fullPath ?? throw new ArgumentNullException(nameof(avatarGameObject)); prefab = avatarGameObject ? avatarGameObject : throw new ArgumentNullException(nameof(avatarGameObject)); descriptor = avatarGameObject.GetComponent <AvatarDescriptor>() ?? throw new AvatarLoadException($"Avatar at '{fullPath}' does not have an AvatarDescriptor"); fileName = Path.GetFileName(fullPath); _logger = loggerProvider.CreateLogger <LoadedAvatar>(descriptor.name); VRIKManager vrikManager = prefab.GetComponentInChildren <VRIKManager>(); #pragma warning disable CS0618 IKManager ikManager = prefab.GetComponentInChildren <IKManager>(); #pragma warning restore CS0618 // migrate IKManager/IKManagerAdvanced to VRIKManager if (ikManager) { if (!vrikManager) { vrikManager = prefab.AddComponent <VRIKManager>(); } _logger.Warning("IKManager and IKManagerAdvanced are deprecated; please migrate to VRIKManager"); ApplyIKManagerFields(vrikManager, ikManager); Object.Destroy(ikManager); } // remove any existing VRIK instances foreach (VRIK existingVrik in prefab.GetComponentsInChildren <VRIK>()) { _logger.Warning($"Found VRIK on '{existingVrik.name}'; manually adding VRIK to an avatar is no longer needed, please remove it"); if (existingVrik && vrikManager && existingVrik.references.isFilled && !vrikManager.areReferencesFilled) { _logger.Warning($"Copying references from VRIK on '{existingVrik.name}'; this is deprecated behaviour and will be removed in a future release"); CopyReferencesFromExistingVrik(vrikManager, existingVrik.references); } Object.Destroy(existingVrik); } _head = prefab.transform.Find("Head"); _leftHand = prefab.transform.Find("LeftHand"); _rightHand = prefab.transform.Find("RightHand"); _pelvis = prefab.transform.Find("Pelvis"); _leftLeg = prefab.transform.Find("LeftLeg"); _rightLeg = prefab.transform.Find("RightLeg"); if (vrikManager) { if (!vrikManager.areReferencesFilled) { vrikManager.AutoDetectReferences(); } FixTrackingReferences(vrikManager); } var poseManager = prefab.GetComponentInChildren <PoseManager>(); isIKAvatar = vrikManager; supportsFullBodyTracking = _pelvis || _leftLeg || _rightLeg; supportsFingerTracking = poseManager && poseManager.isValid; eyeHeight = GetEyeHeight(); armSpan = GetArmSpan(); }
private void CreateAvatar() { Plugin.Log("Creating a new avatar"); avatarInstance = Instantiate(avatarObject, space ?? this.transform); DontDestroyOnLoad(avatarInstance); avatarInstance.name = "Avatar"; StartCoroutine(SetLocalTransforms(avatarInstance.transform)); SetChildrenToLayer(avatarInstance, Config.avatarlayer); VRIK vrik = avatarInstance.GetComponent <VRIK>(); if (vrik == null) { Plugin.Log("Failed to find final ik but it was found previously for some reason"); return; } IKManager ikmanager = avatarInstance.GetComponent <IKManager>(); StartCoroutine(CheckIKTargets(vrik, ikmanager, avatarInstance)); Plugin.Log("Setting VRIK bones"); vrik.references.root = avatarInstance.transform; Transform[] transforms = avatarInstance.GetComponentsInChildren <Transform>(); Plugin.Log($"Length of transforms is {transforms.Length}"); foreach (Transform t in transforms) { switch (t.gameObject.name) { case "Bip001 Pelvis": vrik.references.pelvis = t; break; case "Bip001 Spine": vrik.references.spine = t; break; case "Bip001 L Thigh": vrik.references.leftThigh = t; break; case "Bip001 L Calf": vrik.references.leftCalf = t; break; case "Bip001 L Foot": vrik.references.leftFoot = t; break; case "Bip001 L Toe0": vrik.references.leftToes = t; break; case "Bip001 R Thigh": vrik.references.rightThigh = t; break; case "Bip001 R Calf": vrik.references.rightCalf = t; break; case "Bip001 R Foot": vrik.references.rightFoot = t; break; case "Bip001 R Toe0": vrik.references.rightToes = t; break; case "Bip001 Spine1": vrik.references.chest = t; break; case "Bip001 Neck": vrik.references.neck = t; break; case "Bip001 Head": vrik.references.head = t; break; case "Bip001 L Clavicle": vrik.references.leftShoulder = t; break; case "Bip001 L UpperArm": vrik.references.leftUpperArm = t; break; case "Bip001 L Forearm": vrik.references.leftForearm = t; break; case "Bip001 L Hand": vrik.references.leftHand = t; break; case "Bip001 R Clavicle": vrik.references.rightShoulder = t; break; case "Bip001 R UpperArm": vrik.references.rightUpperArm = t; break; case "Bip001 R Forearm": vrik.references.rightForearm = t; break; case "Bip001 R Hand": vrik.references.rightHand = t; break; default: break; } } if (!vrik.references.isFilled) { Plugin.Log("Failed to populate vrik's references"); } else { Plugin.Log("Successfully populated references"); } //for superhot var smr = avatarInstance.GetComponentInChildren <SkinnedMeshRenderer>(); Shader sh = Shader.Find("XULM/Generic Crystal 0.8 postbeta 2 sided"); if (smr != null && sh != null) { Plugin.Log("We super hot now bois!"); StartCoroutine(SetMaterialsForDude(smr)); } }