protected override void FireWeapon( UnitWeaponSystem _weaponSys , NamedObject _TargetUnit ) { if( true == GlobalSingleton.GetGlobalSingletonObj().GetComponent<AutoPlayMachine>().m_Active ) return ; string weaponComponent = "" ; // check phaser weaponComponent = _weaponSys.FindAbleWeaponComponent( RandomAWeaponKeyword() , _TargetUnit.Name ) ; if( 0 == weaponComponent.Length ) { // Debug.Log( "FireWeapon() no available weapon" ) ; this.SetState( AI_Fire_State.MoveToTarget ) ; return ; } // fire if( true == _weaponSys.ActiveWeapon( weaponComponent , _TargetUnit , ConstName.UnitDataComponentUnitIntagraty ) ) { this.SetState( AI_Fire_State.WaitForReload ) ; } }
// 檢查武器並移動 , 會檢查是在範圍內 還是不能發射 protected override bool CheckWeaponAndMoveToTarget( UnitData _unitData , UnitWeaponSystem _weaponSys , Vector3 _TargetPosition ) { string weaponInRange = "" ; Vector3 vecToTarget = Vector3.zero ; Vector3 norVecToTarget = Vector3.zero ; float angleOfTarget = 0.0f ; float dotOfUp = 0.0f ; string IMPLUSE_ENGINE_RATIO = ConstName.UnitDataComponentImpulseEngineRatio ; // 剛轉換過來不要檢查武器 if( m_State.ElapsedFromLast() > 0.5f ) { // check fire phaser weapon is available weaponInRange = _weaponSys.FindAbleToShootTargetWeaponComponent( RandomAWeaponKeyword() , m_TargetNow.Obj ) ; // Debug.Log( "weaponInRange=" + weaponInRange) ; if( 0 != weaponInRange.Length ) { this.SetState( AI_Fire_State.StopAndFireToTarget ) ; return true ; } } // move to target if( true == MathmaticFunc.FindTargetRelation( this.gameObject , _TargetPosition , ref vecToTarget , ref norVecToTarget , ref angleOfTarget , ref dotOfUp ) ) { if( true == _unitData.standardParameters.ContainsKey( IMPLUSE_ENGINE_RATIO ) ) { // speed to maximum if( vecToTarget.sqrMagnitude > m_MaximumWeaponRange * m_MaximumWeaponRange ) _unitData.standardParameters[ IMPLUSE_ENGINE_RATIO ].ToMax() ; else _unitData.standardParameters[ IMPLUSE_ENGINE_RATIO ].Clear() ; } // angular speed _unitData.AngularRatioHeadTo( angleOfTarget , dotOfUp , 0.1f ) ; } return false ; }
// 前往第二目標 protected bool CheckMoveToTarget( UnitData _unitData , UnitWeaponSystem _weaponSys , Vector3 _TargetPosition , float _ImpulseSpeed = 1.0f ) { Vector3 vecToTarget = Vector3.zero ; Vector3 norVecToTarget = Vector3.zero ; float angleOfTarget = 0.0f ; float dotOfUp = 0.0f ; string IMPLUSE_ENGINE_RATIO = ConstName.UnitDataComponentImpulseEngineRatio ; if( true == MathmaticFunc.FindTargetRelation( this.gameObject , _TargetPosition , ref vecToTarget , ref norVecToTarget , ref angleOfTarget , ref dotOfUp ) ) { if( vecToTarget.sqrMagnitude < m_ReachDistanceSquare ) { this.SetState( AI_Fire_State.MoveToTarget ) ; return true ; } if( true == _unitData.standardParameters.ContainsKey( IMPLUSE_ENGINE_RATIO ) ) { _unitData.standardParameters[ IMPLUSE_ENGINE_RATIO ].now = _unitData.standardParameters[ IMPLUSE_ENGINE_RATIO ].max * _ImpulseSpeed ; } // angular speed _unitData.AngularRatioHeadTo( angleOfTarget , dotOfUp , 0.1f ) ; } return false ; }
// 發射武器 protected override void FireWeapon( UnitWeaponSystem _weaponSys , NamedObject _TargetObject ) { string weaponComponent = "" ; // check phaser weaponComponent = _weaponSys.FindAbleWeaponComponent( RandomAWeaponKeyword() , _TargetObject.Name ) ; if( 0 == weaponComponent.Length ) { // no available weapon this.SetState( AI_Fire_State.MoveToTarget ) ; return ; } // fire if( true == _weaponSys.ActiveWeapon( weaponComponent , _TargetObject , ConstName.UnitDataComponentUnitIntagraty ) ) { this.SetState( AI_Fire_State.WaitForReload ) ; } }
/* # 在函式 TryFireWeapon() 中,呼叫武器系統 依照關鍵字 取得 可以發射的武器部件 # 在函式 TryFireWeapon() 中,呼叫武器系統 傳入 武器部件名稱 目標船艦名稱 發射武器 # 失敗時發出警告聲 # 失敗時顯示武器範圍 */ private bool TryFireWeapon( UnitWeaponSystem _WeaponSys , string _WeaponKeyword , SelectInformation _SelectionInfo ) { // find correct weapon string TargetComponentObjectName = ConstName.CreateComponent3DObjectName( _SelectionInfo.TargetUnitName , _SelectionInfo.m_TargetComponentName ) ; string mainCause = "" ; string weaponComponentName = _WeaponSys.FindAbleWeaponComponent( _WeaponKeyword , TargetComponentObjectName , ref mainCause ) ; bool ret = false ; // Debug.Log( "ActiveTrackorBeam3() weaponComponentName=" + weaponComponentName ) ; if( false == ( ret = _WeaponSys.ActiveWeapon( weaponComponentName , _SelectionInfo.GetTargetUnit() , _SelectionInfo.m_TargetComponentName ) ) ) { // fire weapon fail : beep if( null != m_Audio_WeaponFailBeep ) { // show weapon range ShowWeaponRange( _WeaponKeyword ) ; this.gameObject.audio.PlayOneShot( m_Audio_WeaponFailBeep ) ; MessageQueueManager manager = GlobalSingleton.GetMessageQueueManager() ; if( null != manager ) manager.AddMessage( mainCause ) ; } } return ret ; }
// 取得最大的武器清單,並依照排序 private List<string> RetrievePossibleWeaponListInOrder( UnitData _unitData , UnitWeaponSystem _weaponSys ) { List<string> ret = new List<string>() ; List<string> allWeapens = _unitData.GetAllWeaponComponentNameVec() ; List<string> realWeapons = new List<string>() ; // 剔除trackor beam foreach( string weapon in allWeapens ) { if( -1 == weapon.IndexOf( ConstName.UnitDataComponentWeaponTrackorBeamPrefix ) ) { // no trackor beam realWeapons.Add( weapon ) ; } } while( realWeapons.Count > 0 ) { // 找最遠的 float maxRange = -1 ; string maxRangeString = "" ; foreach( string weapon in realWeapons ) { float rangeThis = _unitData.componentMap[ weapon ].m_WeaponParam.m_Range ; if( rangeThis > maxRange ) { maxRange = rangeThis ; maxRangeString = weapon ; } } realWeapons.Remove( maxRangeString ) ; ret.Add( maxRangeString ) ; } return ret ; }
private string FindMostCloestWeaponComponent( UnitData _unitData , UnitWeaponSystem _weaponSys , NamedObject _possibleUnit , List<string> _possibleWeaponList , ref Dictionary<string , SelectInformation> _fireList ) { string ret = "" ; Dictionary<string,float> angleMap = new Dictionary<string, float>() ; foreach( string weaponComponentName in _possibleWeaponList ) { // Debug.Log( "weaponComponentName=" + weaponComponentName ) ; if( false == _weaponSys.m_WeaponDataMap.ContainsKey( weaponComponentName ) ) { continue ; } // no trackor beam if( -1 != weaponComponentName.IndexOf( ConstName.UnitDataComponentWeaponTrackorBeamPrefix ) ) { continue ; } if( true == _fireList.ContainsKey( weaponComponentName ) ) { // 如果已經用掉了就跳過不作 continue ; } if( 0 != ( _weaponSys.FindAbleWeaponComponent( weaponComponentName , _possibleUnit.Obj ) ).Length ) { WeaponDataSet weapenDataSet = _weaponSys.m_WeaponDataMap[ weaponComponentName ] ; Vector3 toTargetVec = _possibleUnit.Obj.transform.position - this.gameObject.transform.position ; Vector3 toComponentVec = weapenDataSet.Component3DObject.transform.position - this.gameObject.transform.position ; float angle = Vector3.Angle( toComponentVec , toTargetVec ) ; angleMap[ weaponComponentName ] = angle ; // Debug.Log( "toComponentVec=" + toComponentVec ) ; // Debug.Log( "toTargetVec=" + toTargetVec ) ; // Debug.Log( "angleMap[ weaponComponentName ]=" + angle ) ; } } // 尋找angle值最小的 float angleMin = 361.0f ; Dictionary<string,float>.Enumerator e = angleMap.GetEnumerator() ; while( e.MoveNext() ) { if( e.Current.Value < angleMin ) { angleMin = e.Current.Value ; ret = e.Current.Key ; } } // Debug.Log( "FindMostCloestWeaponComponent() ret=" + ret ) ; return ret ; }
private bool TryFireWeaponInMultiAttackMode( UnitData _unitData , UnitSensorSystem _sensorSys , UnitWeaponSystem _weaponSys , UnitSelectionSystem _selectSys , ref Dictionary<string , SelectInformation > _fireList ) { bool ret = false ; // 取得最大可能的瞄準框 int maxSelectionNum = _selectSys.m_MaxSelectionNum ; int selectionIndexNow = 0 ; string [] selectionKeyArray = new string[ _selectSys.m_Selections.Count ] ; _selectSys.m_Selections.Keys.CopyTo( selectionKeyArray , 0 ) ; // 取得最大的武器清單,並依照距離來排序 List<string> possibleWeaponList = RetrievePossibleWeaponListInOrder( _unitData , _weaponSys ) ; // 取得所有的可能敵人,並依照距離來排序 List<NamedObject> possibleUnits = RetrievePossibleUnitInOrder( _sensorSys ); // 目標是讓所有的武器都分別對上不同的敵人.然後設定好所有的瞄準框.最後全部開火. foreach( NamedObject possibleUnit in possibleUnits ) { // Debug.Log( "possibleUnit=" + possibleUnit.Name ) ; // 假如瞄準框已經用盡,離開 if( selectionIndexNow == maxSelectionNum - 1 ) break ; // 每一個單位,找到可以發射的武器,而且最接近中線的武器 string weaponComponentName = FindMostCloestWeaponComponent( _unitData , _weaponSys , possibleUnit , possibleWeaponList , ref _fireList ) ; // Debug.Log( "weaponComponentName=" + weaponComponentName ) ; if( 0 == weaponComponentName.Length ) continue ; // 指定瞄準框的資訊 string key = selectionKeyArray[ selectionIndexNow ] ; _selectSys.m_Selections[ key ].TargetUnitName = possibleUnit.Name ; _selectSys.m_Selections[ key ].TargetUnitObject = possibleUnit.Obj ; // Debug.Log( "_selectSys.m_Selections " + key + " " + possibleUnit.Name ) ; _fireList[ weaponComponentName ] = _selectSys.m_Selections[ key ] ; ++selectionIndexNow ; ret = true ; } // 針對每個瞄準框,發射指定的武器 return ret ; }
// 取得武器距離參數 protected void RetrieveDataMaximumWeaponRange( UnitWeaponSystem _WeaponSys , ref List<string> _weaponKeywords ) { float minWeaponRange = 9999 ; if( _weaponKeywords.Count > 0 ) { foreach( string keyword in _weaponKeywords ) { float weaponRange = _WeaponSys.FindMaximumWeaponRange( keyword ) ; if( weaponRange < minWeaponRange ) minWeaponRange = weaponRange ; } m_MaximumWeaponRange = minWeaponRange ; } else { m_MaximumWeaponRange = _WeaponSys.FindMaximumWeaponRange( "" ) ; } // Debug.Log( "RetrieveDataMaximumWeaponRange() " +m_MaximumWeaponRange ) ; }
protected bool CheckAbleRunAI( out UnitData _UnitData , out UnitWeaponSystem _weaponSys ) { return ( true == CheckUnitData( out _UnitData ) && true == CheckWeaponSys( out _weaponSys ) ) ; }
protected override void FireWeapon( UnitWeaponSystem _weaponSys , NamedObject _TargetUnit ) { if( true == GlobalSingleton.GetGlobalSingletonObj().GetComponent<AutoPlayMachine>().m_Active ) return ; string weaponComponent = "" ; string specifiedWeapon = RandomAWeaponKeyword() ; // 距離太遠 string weaponInRange = _weaponSys.FindAbleToShootTargetWeaponComponent( specifiedWeapon , _TargetUnit.Obj ) ; // Debug.Log( "weaponInRange=" + weaponInRange ) ; if( 0 == weaponInRange.Length ) { // no available weapon this.SetState( AI_Fire_State.MoveToTarget ) ; return ; } string weaponReady = _weaponSys.FindAbleToFireWeaponComponent( specifiedWeapon ) ; #if DEBUG Debug.Log( "FireWeapon() weaponReady=" + weaponReady ) ; #endif if( 0 == weaponReady.Length ) { // no available weapon this.SetState( AI_Fire_State.WaitForReload ) ; return ; } // 檢查正在reload weaponComponent = _weaponSys.FindAbleWeaponComponent( specifiedWeapon , _TargetUnit.Obj ) ; // Debug.Log( "weaponReady=" + weaponComponent ) ; if( 0 == weaponComponent.Length ) { // no available weapon this.SetState( AI_Fire_State.WaitForReload ) ; return ; } // Debug.Log( "_weaponSys.ActiveWeapon" ) ; // fire if( true == _weaponSys.ActiveWeapon( weaponComponent , _TargetUnit , ConstName.UnitDataComponentUnitIntagraty ) ) { this.SetState( AI_Fire_State.WaitForReload ) ; } }
protected virtual bool CheckWeaponSys( out UnitWeaponSystem _weapon ) { _weapon = this.gameObject.GetComponent<UnitWeaponSystem>() ; return ( null != _weapon ) ; }