示例#1
0
        private void ResetTangents(int pointIndex)
        {
            Vector3 position     = GetPosition(pointIndex);
            Vector3 positionNext = GetPosition(SplineUtility.NextIndex(pointIndex, GetPointCount()));
            Vector3 positionPrev = GetPosition(SplineUtility.PreviousIndex(pointIndex, GetPointCount()));
            Vector3 forward      = Vector3.forward;

            if (SplineEditorCache.IsValid() && SplineEditorCache.GetTarget() != null)
            {
                forward = SplineEditorCache.GetTarget().transform.forward;
            }

            float scale = Mathf.Min((positionNext - position).magnitude, (positionPrev - position).magnitude) * 0.33f;

            Vector3 leftTangent  = (positionPrev - position).normalized * scale;
            Vector3 rightTangent = (positionNext - position).normalized * scale;

            if (GetTangentMode(pointIndex) == TangentMode.Continuous)
            {
                SplineUtility.CalculateTangents(position, positionPrev, positionNext, forward, scale, out rightTangent, out leftTangent);
            }

            SetLeftTangent(pointIndex, leftTangent);
            SetRightTangent(pointIndex, rightTangent);
        }
示例#2
0
    // Start is called before the first frame update

    private void Smoothen(SpriteShapeController sc, int pointIndex)
    {
        Vector3 position     = sc.spline.GetPosition(pointIndex);
        Vector3 positionNext = sc.spline.GetPosition(SplineUtility.NextIndex(pointIndex, sc.spline.GetPointCount()));
        Vector3 positionPrev = sc.spline.GetPosition(SplineUtility.PreviousIndex(pointIndex, sc.spline.GetPointCount()));
        Vector3 forward      = gameObject.transform.forward;

        float scale = Mathf.Min((positionNext - position).magnitude, (positionPrev - position).magnitude) * 0.33f;

        Vector3 leftTangent  = (positionPrev - position).normalized * scale;
        Vector3 rightTangent = (positionNext - position).normalized * scale;

        sc.spline.SetTangentMode(pointIndex, ShapeTangentMode.Continuous);
        SplineUtility.CalculateTangents(position, positionPrev, positionNext, forward, scale, out rightTangent, out leftTangent);

        sc.spline.SetLeftTangent(pointIndex, leftTangent);
        sc.spline.SetRightTangent(pointIndex, rightTangent);
    }
示例#3
0
        private void ResetTangents(int pointIndex)
        {
            Vector3 position     = m_Spline.GetPosition(pointIndex);
            Vector3 positionNext = m_Spline.GetPosition(SplineUtility.NextIndex(pointIndex, m_Spline.GetPointCount()));
            Vector3 positionPrev = m_Spline.GetPosition(SplineUtility.PreviousIndex(pointIndex, m_Spline.GetPointCount()));
            Vector3 forward      = (m_CurrentEditor.target as SpriteShapeController).transform.forward;
            float   scale        = Mathf.Min((positionNext - position).magnitude, (positionPrev - position).magnitude) * 0.33f;

            Vector3 leftTangent  = (positionPrev - position).normalized * scale;
            Vector3 rightTangent = (positionNext - position).normalized * scale;

            if (m_Spline.GetTangentMode(pointIndex) == ShapeTangentMode.Continuous)
            {
                SplineUtility.CalculateTangents(position, positionPrev, positionNext, forward, scale, out rightTangent, out leftTangent);
            }

            m_Spline.SetLeftTangent(pointIndex, leftTangent);
            m_Spline.SetRightTangent(pointIndex, rightTangent);
        }
    // Update is called once per frame
    void Update()
    {
        var mouseWorldPos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
        var mousePos      = new Vector2(mouseWorldPos.x, mouseWorldPos.y);

        if (state == DragState.None && Input.GetMouseButton(0))
        {
            var hits = new List <RaycastHit2D>();
            var cf   = new ContactFilter2D();
            cf.NoFilter();
            int              hitCount   = Physics2D.CircleCast(mousePos, 0.1f, Vector2.zero, cf, hits);
            Vector2          startPoint = Vector2.zero;
            GameObject       obj        = null;
            PlantSectionType?plantType  = null;
            // Find the highest priority growth thing (seed > medium)
            for (int i = 0; i < hitCount; i++)
            {
                var hit      = hits[i];
                var iObj     = hit.collider.gameObject;
                var growable = iObj.GetComponent <Growable>();
                if (growable && !obj)
                {
                    obj        = iObj;
                    startPoint = hit.point;
                    plantType  = growable.rootType;
                }
                else if (growable)
                {
                    if (growable.rootType == PlantSectionType.Seed || plantType != PlantSectionType.Seed)
                    {
                        obj        = iObj;
                        startPoint = hit.point;
                        plantType  = growable.rootType;
                    }
                }
            }
            if (obj != null && plantType != null)
            {
                // First, check if it's the end point
                var spline = obj.GetComponent <SpriteShapeController>()?.spline;
                if (spline != null)
                {
                    var pointCount = spline.GetPointCount();
                    var lastWorld  = obj.transform.position + spline.GetPosition(pointCount - 1);
                    var last       = new Vector2(lastWorld.x, lastWorld.y);
                    if ((last - mousePos).magnitude < 0.4f)
                    {
                        // We're close enough to the end, we should just continue growing this one
                        state            = DragState.Dragging;
                        currentlyGrowing = obj;
                        return;
                    }
                }
                switch (plantType)
                {
                case PlantSectionType.Seed: {
                    // Unlock the camera if this is the first time we've clicked on a seed
                    focus.startupLock = false;
                    // If we're clicking on a seed, drop into the deciding state
                    state      = DragState.Deciding_Seed;
                    dragStart  = startPoint;
                    dragParent = obj.GetComponent <Growable>();
                    obj.GetComponent <Animator>().SetTrigger("StopWiggle");
                } break;

                case PlantSectionType.MediumRoot: {
                    state      = DragState.Deciding_Medium_Root;
                    dragStart  = startPoint;
                    dragParent = obj.GetComponent <Growable>();
                } break;

                default: {
                } break;
                }
            }
            return;
        }
        if (state == DragState.Deciding_Seed && Input.GetMouseButton(0))
        {
            var delta = mousePos - dragStart;
            if (delta.sqrMagnitude < .5f)
            {
                // Update the indicator position, or something?
            }
            else
            {
                // Decide what to spawn based on whether you went up or down
                if (delta.y <= 0)
                {
                    // They went down, spawn a root!
                    currentlyGrowing = SpawnOffshoot(dragParent, PlantSectionType.MediumRoot, dragStart, mousePos);
                    state            = DragState.Dragging;
                }
                else
                {
                    currentlyGrowing = SpawnOffshoot(dragParent, PlantSectionType.SkinnyPlant, dragStart, mousePos);
                    state            = DragState.Dragging;
                }
            }
            return;
        }
        if (state == DragState.Deciding_Medium_Root && Input.GetMouseButton(0))
        {
            var delta = mousePos - dragStart;
            if (delta.sqrMagnitude < .5f)
            {
                // Update the indicator position, or something?
            }
            else
            {
                currentlyGrowing = SpawnOffshoot(dragParent, PlantSectionType.SkinnyRoot, dragStart, mousePos);
                state            = DragState.Dragging;
            }
        }
        if (state == DragState.Dragging && Input.GetMouseButton(0))
        {
            var growable = currentlyGrowing.GetComponent <Growable>().growable;
            if (!growable)
            {
                return;
            }
            var currentType = currentlyGrowing.GetComponent <Growable>().rootType;
            var spline      = currentlyGrowing.GetComponent <SpriteShapeController>().spline;
            var pointCount  = spline.GetPointCount();
            // Check the length of the last segment
            var basePosWorld = currentlyGrowing.transform.position;
            var lastWorld    = spline.GetPosition(pointCount - 1);
            var prevWorld    = spline.GetPosition(pointCount - 2);
            var basePos      = new Vector2(basePosWorld.x, basePosWorld.y);
            var last         = new Vector2(lastWorld.x, lastWorld.y);
            var prev         = new Vector2(prevWorld.x, prevWorld.y);

            // Grow the spline slightly
            var growDir = mousePos - (basePos + last);
            segmentTime += Time.deltaTime;
            var currentCost = currentType == PlantSectionType.MediumRoot ? 30 : 5;
            if (growDir.sqrMagnitude > .001)
            {
                var growDirN    = growDir.normalized;
                var growSpeed   = currentType == PlantSectionType.MediumRoot ? 0.5f : 1.5f;
                var newPos      = last + growDirN * growSpeed * Time.deltaTime;
                var newPosWorld = basePos + newPos;

                // Check for rocks
                bool blocked = false;
                foreach (var rock in impassables)
                {
                    var collider = rock.GetComponent <Collider2D>();
                    if (collider.OverlapPoint(newPosWorld))
                    {
                        newPosWorld = collider.ClosestPoint(basePos + last);
                        newPos      = newPosWorld - basePos;
                    }
                }
                // If roots, make sure we stay below ground
                if (currentType == PlantSectionType.SkinnyRoot ||
                    currentType == PlantSectionType.MediumRoot
                    )
                {
                    newPosWorld = dirt.GetComponent <Collider2D>().ClosestPoint(basePos + newPos);
                    newPos      = newPosWorld - basePos;
                }

                var newPosRel = new Vector3(newPos.x, newPos.y, 0.0f);

                if (newPosWorld.y > focus.plantHeight)
                {
                    focus.plantHeight = newPosWorld.y;
                }
                if (newPosWorld.y < focus.plantDepth)
                {
                    focus.plantDepth = newPosWorld.y;
                }

                var turningRadius = currentType == PlantSectionType.MediumRoot ? 0.7f : 0.3f;
                if ((last - prev).sqrMagnitude < turningRadius && segmentTime < 2)
                {
                    spline.SetPosition(pointCount - 1, newPosRel);
                }
                else if (currentCost <= minerals)
                {
                    segmentTime = 0.0f;
                    var midpoint = (lastWorld + prevWorld) / 2;
                    spline.SetPosition(pointCount - 1, midpoint);
                    spline.InsertPointAt(pointCount, newPosRel);
                    // we just added something to the spline, so pointCount now refers to the last
                    minerals -= currentCost;
                    switch (currentType)
                    {
                    case PlantSectionType.MediumRoot: {
                        spline.SetHeight(pointCount, .3f);
                    } break;

                    case PlantSectionType.SkinnyRoot: {
                        spline.SetHeight(pointCount, .1f);
                    } break;

                    case PlantSectionType.SkinnyPlant: {
                        spline.SetHeight(pointCount, .2f);
                    } break;
                    }
                    // pointCount - 1 is the second-to-last
                    spline.SetTangentMode(pointCount - 1, ShapeTangentMode.Continuous);
                    Vector3 right;
                    Vector3 left;
                    SplineUtility.CalculateTangents(
                        lastWorld, prevWorld, newPosRel, Vector2.zero,
                        .2f, out right, out left
                        );
                    spline.SetLeftTangent(pointCount - 1, left);
                    spline.SetRightTangent(pointCount - 1, right);
                    float length = 0;
                    for (var i = 0; i < pointCount - 1; i++)
                    {
                        if (i > 0)
                        {
                            length += (spline.GetPosition(i) - spline.GetPosition(i - 1)).magnitude;
                        }
                        var maxH = currentType == PlantSectionType.MediumRoot ? 0.7f : 0.5f;
                        var h    = spline.GetHeight(i);
                        var dH   = (maxH - h) / 50f;
                        var newH = h + dH;
                        spline.SetHeight(i, newH);
                    }
                    var maxLength = currentType == PlantSectionType.SkinnyPlant ? 75 : 25;
                    if (length > maxLength)
                    {
                        currentlyGrowing.GetComponent <Growable>().growable = false;
                    }
                }
            }
        }
        if (!Input.GetMouseButton(0))
        {
            state            = DragState.None;
            dragStart        = Vector2.zero;
            currentlyGrowing = null;
        }
    }