【问题标题】:Unity Error building Player because scripts had compiler errorsUnity 错误构建播放器,因为脚本有编译器错误
【发布时间】:2020-09-01 11:54:50
【问题描述】:

我知道这是一个众所周知的问题。但我不知道该怎么办。

(在新标签中打开图像以获得更好的清晰度)

该脚本 FastIKFabric.cs 运行良好(而且它来自资产商店),正如您在检查器中看到的那样,它没有任何 using UnityEditor;。第 250 行是该脚本的最后一行,} 已正确关闭。正如我所说,脚本没有任何错误。

我能做什么?提前感谢您的任何回答! :)

这是脚本:

#if UNITY_EDITOR
#endif
using UnityEngine;

namespace DitzelGames.FastIK
{
    /// <summary>
    /// Fabrik IK Solver
    /// </summary>
    public class FastIKFabric : MonoBehaviour
    {
        /// <summary>
        /// Chain length of bones
        /// </summary>
        public int ChainLength = 2;

        /// <summary>
        /// Target the chain should bent to
        /// </summary>
        public Transform Target;
        public Transform Pole;

        /// <summary>
        /// Solver iterations per update
        /// </summary>
        [Header("Solver Parameters")]
        public int Iterations = 10;

        /// <summary>
        /// Distance when the solver stops
        /// </summary>
        public float Delta = 0.001f;

        /// <summary>
        /// Strength of going back to the start position.
        /// </summary>
        [Range(0, 1)]
        public float SnapBackStrength = 1f;


        protected float[] BonesLength; //Target to Origin
        protected float CompleteLength;
        protected Transform[] Bones;
        protected Vector3[] Positions;
        protected Vector3[] StartDirectionSucc;
        protected Quaternion[] StartRotationBone;
        protected Quaternion StartRotationTarget;
        protected Transform Root;


        // Start is called before the first frame update
        void Awake()
        {
            Init();
        }

        void Init()
        {
            //initial array
            Bones = new Transform[ChainLength + 1];
            Positions = new Vector3[ChainLength + 1];
            BonesLength = new float[ChainLength];
            StartDirectionSucc = new Vector3[ChainLength + 1];
            StartRotationBone = new Quaternion[ChainLength + 1];

            //find root
            Root = transform;
            for (var i = 0; i <= ChainLength; i++)
            {
                if (Root == null)
                    throw new UnityException("The chain value is longer than the ancestor chain!");
                Root = Root.parent;
            }

            //init target
            if (Target == null)
            {
                Target = new GameObject(gameObject.name + " Target").transform;
                SetPositionRootSpace(Target, GetPositionRootSpace(transform));
            }
            StartRotationTarget = GetRotationRootSpace(Target);


            //init data
            var current = transform;
            CompleteLength = 0;
            for (var i = Bones.Length - 1; i >= 0; i--)
            {
                Bones[i] = current;
                StartRotationBone[i] = GetRotationRootSpace(current);

                if (i == Bones.Length - 1)
                {
                    //leaf
                    StartDirectionSucc[i] = GetPositionRootSpace(Target) - GetPositionRootSpace(current);
                }
                else
                {
                    //mid bone
                    StartDirectionSucc[i] = GetPositionRootSpace(Bones[i + 1]) - GetPositionRootSpace(current);
                    BonesLength[i] = StartDirectionSucc[i].magnitude;
                    CompleteLength += BonesLength[i];
                }

                current = current.parent;
            }



        }

        // Update is called once per frame
        void LateUpdate()
        {
            ResolveIK();
        }

        private void ResolveIK()
        {
            if (Target == null)
                return;

            if (BonesLength.Length != ChainLength)
                Init();

            //Fabric

            //  root
            //  (bone0) (bonelen 0) (bone1) (bonelen 1) (bone2)...
            //   x--------------------x--------------------x---...

            //get position
            for (int i = 0; i < Bones.Length; i++)
                Positions[i] = GetPositionRootSpace(Bones[i]);

            var targetPosition = GetPositionRootSpace(Target);
            var targetRotation = GetRotationRootSpace(Target);

            //1st is possible to reach?
            if ((targetPosition - GetPositionRootSpace(Bones[0])).sqrMagnitude >= CompleteLength * CompleteLength)
            {
                //just strech it
                var direction = (targetPosition - Positions[0]).normalized;
                //set everything after root
                for (int i = 1; i < Positions.Length; i++)
                    Positions[i] = Positions[i - 1] + direction * BonesLength[i - 1];
            }
            else
            {
                for (int i = 0; i < Positions.Length - 1; i++)
                    Positions[i + 1] = Vector3.Lerp(Positions[i + 1], Positions[i] + StartDirectionSucc[i], SnapBackStrength);

                for (int iteration = 0; iteration < Iterations; iteration++)
                {
                    //https://www.youtube.com/watch?v=UNoX65PRehA
                    //back
                    for (int i = Positions.Length - 1; i > 0; i--)
                    {
                        if (i == Positions.Length - 1)
                            Positions[i] = targetPosition; //set it to target
                        else
                            Positions[i] = Positions[i + 1] + (Positions[i] - Positions[i + 1]).normalized * BonesLength[i]; //set in line on distance
                    }

                    //forward
                    for (int i = 1; i < Positions.Length; i++)
                        Positions[i] = Positions[i - 1] + (Positions[i] - Positions[i - 1]).normalized * BonesLength[i - 1];

                    //close enough?
                    if ((Positions[Positions.Length - 1] - targetPosition).sqrMagnitude < Delta * Delta)
                        break;
                }
            }

            //move towards pole
            if (Pole != null)
            {
                var polePosition = GetPositionRootSpace(Pole);
                for (int i = 1; i < Positions.Length - 1; i++)
                {
                    var plane = new Plane(Positions[i + 1] - Positions[i - 1], Positions[i - 1]);
                    var projectedPole = plane.ClosestPointOnPlane(polePosition);
                    var projectedBone = plane.ClosestPointOnPlane(Positions[i]);
                    var angle = Vector3.SignedAngle(projectedBone - Positions[i - 1], projectedPole - Positions[i - 1], plane.normal);
                    Positions[i] = Quaternion.AngleAxis(angle, plane.normal) * (Positions[i] - Positions[i - 1]) + Positions[i - 1];
                }
            }

            //set position & rotation
            for (int i = 0; i < Positions.Length; i++)
            {
                if (i == Positions.Length - 1)
                    SetRotationRootSpace(Bones[i], Quaternion.Inverse(targetRotation) * StartRotationTarget * Quaternion.Inverse(StartRotationBone[i]));
                else
                    SetRotationRootSpace(Bones[i], Quaternion.FromToRotation(StartDirectionSucc[i], Positions[i + 1] - Positions[i]) * Quaternion.Inverse(StartRotationBone[i]));
                SetPositionRootSpace(Bones[i], Positions[i]);
            }
        }

        private Vector3 GetPositionRootSpace(Transform current)
        {
            if (Root == null)
                return current.position;
            else
                return Quaternion.Inverse(Root.rotation) * (current.position - Root.position);
        }

        private void SetPositionRootSpace(Transform current, Vector3 position)
        {
            if (Root == null)
                current.position = position;
            else
                current.position = Root.rotation * position + Root.position;
        }

        private Quaternion GetRotationRootSpace(Transform current)
        {
            //inverse(after) * before => rot: before -> after
            if (Root == null)
                return current.rotation;
            else
                return Quaternion.Inverse(current.rotation) * Root.rotation;
        }

        private void SetRotationRootSpace(Transform current, Quaternion rotation)
        {
            if (Root == null)
                current.rotation = rotation;
            else
                current.rotation = Root.rotation * rotation;
        }

        void OnDrawGizmos()
        {
#if UNITY_EDITOR
            var current = this.transform;
            for (int i = 0; i < ChainLength && current != null && current.parent != null; i++)
            {
                var scale = Vector3.Distance(current.position, current.parent.position) * 0.1f;
                //Handles.matrix = Matrix4x4.TRS(current.position, Quaternion.FromToRotation(Vector3.up, current.parent.position - current.position), new Vector3(scale, Vector3.Distance(current.parent.position, current.position), scale));
                //Handles.color = Color.green;
                //Handles.DrawWireCube(Vector3.up * 0.5f, Vector3.one);
                current = current.parent;
            }
        }
#endif

    }
}

【问题讨论】:

    标签: c# unity3d build compiler-errors scripting


    【解决方案1】:

    我不相信你,编译器不会说谎。也许您正确关闭了它,但是您是否在重建之前将脚本保存在 Visual Studio 中??

    【讨论】:

    • visual studio中的脚本没有任何错误,vs应该下划线但没有下划线。并且还说 0 个错误和 0 个警告与我在前一段时间和它工作时使用过这个脚本。我根本没有更改它,因为它来自资产商店并且运行良好。
    • 请发布完整的脚本
    • 问题在哪里?
    • 是的,有时 vs 并没有捕捉到我只想检查的所有内容
    • 你错过了一个 curley,只需在底部放一个以关闭命名空间,它应该可以工作,只需瞥一眼它
    【解决方案2】:

    只需 2 美分。一个很长的答案,只是为了说明问题并让其他人更容易看到。


    花一点时间考虑一下预处理器指令 (#if UNITY_EDITOR),因此,如果我们在 UnityEditor 内部/使用 UnityEditor,指令 (#if...#endif) 中的代码将处于活动状态。

    既然我们有:

    // previous code ...
    
            void OnDrawGizmos()
            {
    #if UNITY_EDITOR
                var current = this.transform;
                for (int i = 0; i < ChainLength && current != null && current.parent != null; i++)
                {
                    // ...code...
                }
            }
    #endif
    
            // rest of the code ...
            private void LikeAnotherMethod() 
            {
                ....
            }
    

    当我们在 UNITY_EDITOR 时将等于;

    // previous code ...
    
            void OnDrawGizmos()
            {
                var current = this.transform;
                for (int i = 0; i < ChainLength && current != null && current.parent != null; i++)
                {
                    // ...code...
                }
            }
    
            // rest of the code ...
            private void LikeAnotherMethod() 
            {
                ....
            }
    

    但是,如果我们不在 UnityEditor 的世界中(例如在 Android、iOS 或 MacOSX 游戏中),那么这些预处理器指令中的所有内容都将消失。

    所以,在我们的例子中;

    // previous code ...
    
            void OnDrawGizmos()
            {
    #if UNITY_EDITOR
    // nope        var current = this.transform;
    // nope        for (int i = 0; i < ChainLength && current != null && current.parent != null; i++)
    // nope         {
    // nope             // ...code...
    // nope         }
    // nope }
    #endif
    
            // rest of the code ...
            private void LikeAnotherMethod() 
            {
                ....
            }
    

    跟;

    // previous code ...
    
            void OnDrawGizmos()
            {
    
    
            // rest of the code ...
            private void LikeAnotherMethod() 
            {
                ....
            }
    

    所以在最后一段代码中更容易看到//rest of the code 之前缺少{。这就是问题的原因。 VisualStudio(或其他 IDE 同时不会抱怨,因为在 UnityEditor 世界中一切正常,但一旦构建应用程序就会失败。)


    一种可能的解决方法是将#endif 预处理器指令移动一行:

    // previous code ...
    
            void OnDrawGizmos()
            {
    #if UNITY_EDITOR
                var current = this.transform;
                for (int i = 0; i < ChainLength && current != null && current.parent != null; i++)
                {
                    // ...code...
                }
    #endif
            }
    
    
            // rest of the code ...
            private void LikeAnotherMethod() 
            {
                ....
            }
    

    【讨论】:

    • 谢谢,现在我明白了它是如何与{ 一起工作的 :)。
    猜你喜欢
    • 2020-08-24
    • 1970-01-01
    • 2017-07-24
    • 2018-03-21
    • 2018-03-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多