如何在跨子例程的模块中处理Fortran全局可分配变量

时间:2019-02-25 04:57:37

标签: module fortran global-variables allocatable-array

我有以下模块,该模块具有可分配变量,该变量在模块中定义,在子例程中分配,然后在第一个子例程调用的第二个子例程中使用。在这种情况下,我是否必须将变量传递给第二个子例程并声明using System.Collections; using System.Collections.Generic; using UnityEngine; public class FlyToOverTerrain : MonoBehaviour { public Transform target; public float desiredHeight = 10f; public float flightSmoothTime = 10f; public float maxFlightspeed = 10f; public float flightAcceleration = 1f; public float levelingSmoothTime = 0.5f; public float maxLevelingSpeed = 10000f; public float levelingAcceleration = 2f; private Vector3 flightVelocity = Vector3.zero; private float heightVelocity = 0f; private void LateUpdate() { Vector3 position = transform.position; float currentHeight = position.y; if (target && flightAcceleration > float.Epsilon) { position = Vector3.SmoothDamp(position, target.position, ref flightVelocity, flightSmoothTime / flightAcceleration, maxFlightspeed, flightAcceleration * Time.deltaTime); } if (levelingAcceleration > float.Epsilon) { float targetHeight = Terrain.activeTerrain.SampleHeight(position) + desiredHeight; position.y = Mathf.SmoothDamp(currentHeight, targetHeight, ref heightVelocity, levelingSmoothTime / levelingAcceleration, maxLevelingSpeed, levelingAcceleration * Time.deltaTime); } transform.position = position; } } ?还是因为它是一个全局变量,所以不需要将其作为参数传递?

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[System.Serializable]
public class PatrolData
{
    public Transform target = null;
    public float minDistance = 5f;
    public float lingerDuration = 5f;
    public float desiredHeight = 10f;
    public float flightSmoothTime = 10f;
    public float maxFlightspeed = 10f;
    public float flightAcceleration = 1f;
    public float levelingSmoothTime = 0.5f;
    public float maxLevelingSpeed = 10000f;
    public float levelingAcceleration = 2f;
}

public class PatrolOverTerrain : MonoBehaviour
{
    public FlyToOverTerrain flyOverTerrain;
    public LookAtCamera lookAtCamera;
    public enum PatrolMode { Clamp, Wrap, PingPong };
    public PatrolData[] patrolPoints;
    public PatrolMode mode = PatrolMode.Wrap;

    private int iterator = 0;
    private int index = 0;
    private float lingerDuration = 0f;
    private int overallLength = 0;

    public bool autoFreedomPatrol = false;
    public List<GameObject> Targets = new List<GameObject>();
    public string tagName;
    public Vector3 distanceFromTarget;

    public void Start()
    {
        if (tagName != "")
        {
            GameObject[] tempObj = GameObject.FindGameObjectsWithTag(tagName);

            for (int i = 0; i < tempObj.Length; i++)
            {
                //Add to list only if it does not exist
                if (!Targets.Contains(tempObj[i]))
                {
                    Targets.Add(tempObj[i]);
                }
            }

            //Get the current Size
            if (tempObj != null)
            {
                overallLength = Targets.Count;
            }

            GeneratePatrolPoints();
        }
    }

    private void OnEnable()
    {
        if (patrolPoints.Length > 0)
        {
            lingerDuration = patrolPoints[index].lingerDuration;
        }
    }

    private void Update()
    {
        int length = patrolPoints.Length;
        if (!flyOverTerrain) return;
        if (patrolPoints.Length < 1) return;
        if (index < 0) return;

        var patrol = patrolPoints[index];
        if (lingerDuration <= 0)
        {
            iterator++;
            switch (mode)
            {
                case PatrolMode.Clamp:
                    index = (iterator >= length) ? -1 : iterator;
                    break;
                case PatrolMode.Wrap:
                    iterator = Modulus(iterator, length);
                    index = iterator;
                    break;
                case PatrolMode.PingPong:
                    index = PingPong(iterator, length);
                    break;
            }
            if (index < 0) return;

            patrol = patrolPoints[index];

            flyOverTerrain.target = patrol.target;
            flyOverTerrain.desiredHeight = patrol.desiredHeight;
            flyOverTerrain.flightSmoothTime = patrol.flightSmoothTime;
            flyOverTerrain.maxFlightspeed = patrol.maxFlightspeed;
            flyOverTerrain.flightAcceleration = patrol.flightAcceleration;
            flyOverTerrain.levelingSmoothTime = patrol.levelingSmoothTime;
            flyOverTerrain.maxLevelingSpeed = patrol.maxLevelingSpeed;
            flyOverTerrain.levelingAcceleration = patrol.levelingAcceleration;

            lookAtCamera.target = patrol.target;
            lookAtCamera.RotationSpeed = 3;

            lingerDuration = patrolPoints[index].lingerDuration;
        }

        Vector3 targetOffset = Vector3.zero;
        if ((bool)patrol.target)
        {
            targetOffset = transform.position - patrol.target.position;
        }

        float sqrDistance = patrol.minDistance * patrol.minDistance;
        if (targetOffset.sqrMagnitude <= sqrDistance)
        {
            flyOverTerrain.target = null;
            lookAtCamera.target = null;
            lingerDuration -= Time.deltaTime;
        }
        else
        {
            flyOverTerrain.target = patrol.target;
            lookAtCamera.target = patrol.target;
        }
        distanceFromTarget = transform.position - patrol.target.position;
    }

    private int PingPong(int baseNumber, int limit)
    {
        if (limit < 2) return 0;
        return limit - Mathf.Abs(limit - Modulus(baseNumber, limit + (limit - 2)) - 1) - 1;
    }

    private int Modulus(int baseNumber, int modulus)
    {
        return (modulus == 0) ? baseNumber : baseNumber - modulus * (int)Mathf.Floor(baseNumber / (float)modulus);
    }

    public void GeneratePatrolPoints()
    {
        patrolPoints = new PatrolData[Targets.Count];
        for (int i = 0; i < patrolPoints.Length; i++)
        {
            patrolPoints[i] = new PatrolData();
            patrolPoints[i].target = Targets[i].transform;
            patrolPoints[i].minDistance = 30f;
            patrolPoints[i].lingerDuration = 3f;
            patrolPoints[i].desiredHeight = 20f;
            patrolPoints[i].flightSmoothTime = 10f;
            patrolPoints[i].maxFlightspeed = 10f;
            patrolPoints[i].flightAcceleration = 3f;
            patrolPoints[i].levelingSmoothTime = 0.5f;
            patrolPoints[i].maxLevelingSpeed = 10000f;
            patrolPoints[i].levelingAcceleration = 2f;
        }
    }
}

1 个答案:

答案 0 :(得分:3)

  

我是否必须将变量传递给第二个子例程并声明INTENT(inout)

不,你不知道。默认情况下,在模块主体中标出的任何变量都具有save属性。但是,您必须确保仅在执行第一个子例程之后才调用第二个子例程,否则程序将因total尚未初始化而失败。

模块中声明的所有函数和子例程都可以通过主机关联访问total


顺便说一句,您应该在代码中解决一些问题,就像@PierredeBuyl在评论中提到的那样:

  • 在模块主体中声明的变量默认情况下被保存;您应该删除SAVE语句。
  • 在模块中声明的过程从模块范围继承了IMPLICIT伪指令,如果您不对其进行更改,则无需在子例程中重新声明它。
  • 您缺少my_subr1中参数的声明。