//アバターターゲットの座標管理のために //ベクター構造体を定義する class Vector2{ public float x; public float y; public Vector2(){ x=0; y=0; } public void Copy(Vector2 v){ x=v.x; y=v.y; } public void Add(Vector2 v){ x+=v.x; y+=v.y; } } class AvatarTargetInfo{ public Vector2 currentPos_;//現在選択中のプレイヤーの画面上の2D座標(UIとして表示するため) public Vector3 currentPlayerPos_;//現在選択中のプレイヤーの3D空間上の座標 public bool isShownTarget; public string playerID;//選択中のPlayerのID public string playerIDIngame;//選択中のPlayerのID public AvatarTargetInfo(){ isShownTarget=false; currentPos_=new Vector2(); currentPlayerPos_=new Vector3(); } } //アバターターゲット(選択したプレイヤーへのレティクル)おnコントロールコンポーネント component AvatarTargetModel { //以下の定数はターゲットの位置調整用の定数 //そのままやると、GetPosで得られる座標は「足元」になってしまうため //「腰くらい」の高さを設定 // プレイヤーのvrmにheadがあればその高さの2/3にするが、これを持っていないモデルもあるためその場合は // 90cmの決め打ちとしている const float target_offset_y=0.9;//90cmくらいをターゲット位置に const float target_offset_yrate=0.67;//身長の2/3くらいをターゲット位置に private AvatarTargetInfo avatarTargetInfo_;//現在選択中のアバターに対する情報 private bool isHideTarget_;//一定以上離れたら不可視にするためのフラグ private int frameCount_; public AvatarTargetModel(){ avatarTargetInfo_=new AvatarTargetInfo(); isHideTarget_=false; frameCount_=0; } public AvatarTargetInfo GetAvatarTargetInfo(){ return avatarTargetInfo_; } //GUIボタンクリック public void OnClickedButton(string layerName,string btnName){ if(layerName!="other_profile"){//プロフィール表示中はアバター選択を解除しない if(layerName=="avatar_target"){ if(btnName == "profile_btn"){ ProfController profCtrl=GetProfController(); profCtrl.LoginCheckForProfile(); } else if(btnName == "private_chat_btn"){ //個別チャットボタンをフォーカスUIから選択した時の処理 Player SelfPlayer = hsPlayerGet(); string UserCodeSelf = SelfPlayer.GetCustomState("UserCode"); string UserTypeSelf = SelfPlayer.GetCustomState("UserType"); { //テキストチャットを表示 LayerBundle layer = hsLayerGet("textchat_common"); if(layer !== null) { layer.CallComponentMethod("TCViewModel", "StartIndividualChat", avatarTargetInfo_.playerIDIngame); } } } }else{ //選択解除 DeactivateTarget(); } } } //アバタークリック public void OnClickedAvatar(string playerID) { //VRの時は無効! if(hsSystemIsVRMode()){ return; } Player player=hsPlayerGetByID(playerID); if(player!==null){ if(IsSelectableAvatar(player)){ ProfController profCtrl=GetProfController(); //同じプレイヤーがクリックされたら解除のまま if(playerID==profCtrl.GetLockingPlayerID()){ DeactivateTarget(); return; } profCtrl.LockPlayer(playerID); //currentLockingPlayer_=player; UpdateCurrentPlayerPos(); hsCanvasSetLayerShow("avatar_target", true); float px,py; hsCanvasWorldToScreenPos(avatarTargetInfo_.currentPlayerPos_,px,py); avatarTargetInfo_.currentPos_.x=px; avatarTargetInfo_.currentPos_.y=py; string UserCode = player.GetCustomState("UserCode"); string UserType = player.GetCustomState("UserType"); avatarTargetInfo_.playerID = UserCode; avatarTargetInfo_.playerIDIngame = playerID; //一旦ターゲットの表示をデフォルト(不可視)に戻す DeactivateTarget(); profCtrl.LockPlayer(playerID);//DeactivateでCurrentPlayerID_がリセットされるためここに記述 //その後また選択状態表示に切り替える ActivateTarget(); //選択中のレティクルGUIを表示する DrawTargetGUI(avatarTargetInfo_.currentPos_,true); } }else{ //選択したアバターがなぜかnullだったら DeactivateLockedPlayer(); } } private void OnActivatedTargetFocus(bool IsActivate, string PlayerID, string ItemName) { if(IsActivate) { hsCanvasResetToggleDefault("Toggle_TargetFocus"); hsCanvasToggleChange("Toggle_TargetFocus"); } else { hsCanvasResetToggleDefault("Toggle_TargetFocus"); // ターゲットを解除する DeactivateTarget(); } } public void DeactivateLockedPlayer(){ ProfController profCtrl=GetProfController(); profCtrl.UnlockPlayer(); DeactivateTarget(); } private ProfController GetProfController(){ LayerBundle layerVCC=hsLayerGet("other_profile"); if(layerVCC===null){ hsSystemOutput("other_profileレイヤーがNULL\n"); return null; }else{ ProfController profCtrl=system.Layer_GetComponentByName("other_profile"); if(profCtrl===null){ hsSystemOutput("ProfControllerコンポーネントがNULL\n"); return null; }else{ return profCtrl; } } return null; } private void HideTargetCircle(){ hsCanvasResetToggleDefault("avatar_target_image_1_toggle"); hsCanvasResetToggleDefault("avatar_target_image_2_toggle"); hsCanvasResetToggleDefault("avatar_profile_toggle"); hsCanvasResetToggleDefault("avatar_target_show_toggle"); isHideTarget_=true; } //ターゲッティングを無効にする private void DeactivateTarget(){ avatarTargetInfo_.isShownTarget=false; HideTargetCircle(); ProfController profCtrl=GetProfController(); profCtrl.UnlockPlayer(); } //ターゲッティングを有効にする private void ActivateTarget(){ hsCanvasToggleChange("avatar_target_image_1_toggle"); hsCanvasToggleChange("avatar_profile_toggle"); hsCanvasToggleChange("avatar_target_show_toggle"); avatarTargetInfo_.isShownTarget=true; isHideTarget_=false; } private bool IsSelectableAvatar(Player player){ if(player===null){ return false; } Player myPlayer=hsPlayerGet(); //20m以内ならtrue Vector3 playerPos = player.GetPos(); Vector3 myPlayerPos = myPlayer.GetPos(); return playerPos.Distance(myPlayerPos)<=20.0f; } //アバターターゲットの座標をプレイヤーの腰あたりに補正する private void UpdateCurrentPlayerPos(){ ProfController profCtrl=GetProfController(); Player player = profCtrl.GetCurrentLockingPlayer(); Vector3 playerPos=player.GetPos(); avatarTargetInfo_.currentPlayerPos_=playerPos; float height=player.GetHeadHeight(); if(height==0.0){ avatarTargetInfo_.currentPlayerPos_.y+=target_offset_y;//デフォだと足元なので補正(headボーンがない場合に規定値に) }else{ avatarTargetInfo_.currentPlayerPos_.y+=player.GetHeadHeight()*target_offset_yrate;//デフォだと足元なので補正(目線の2/3に) } } //ロード直後 public void OnLoaded() { DeactivateTarget(); } private void DrawTargetGUI(Vector2 pos ,bool changeFlg){ if(changeFlg){ hsCanvasToggleChange("avatar_target_image_1_toggle"); hsCanvasToggleChange("avatar_target_image_2_toggle"); } hsCanvasSetGUIPos("avatar_target",hsCanvasIsPortrait(),"avatar_target_image_1",pos.x,pos.y); hsCanvasSetGUIPos("avatar_target",hsCanvasIsPortrait(),"avatar_target_image_2",pos.x,pos.y); int OffsetX = (hsCanvasIsPortrait())? 36 : 24; hsCanvasSetGUIPos("avatar_target",hsCanvasIsPortrait(),"profile_btn", pos.x + OffsetX, pos.y); hsCanvasSetGUIPos("avatar_target",hsCanvasIsPortrait(),"private_chat_btn", pos.x + OffsetX, pos.y + (hsCanvasIsPortrait()? 128 : 32) * 1); hsCanvasSetGUIPos("avatar_target",hsCanvasIsPortrait(),"defocus_btn", pos.x + OffsetX, pos.y + (hsCanvasIsPortrait()? 128 : 32) * 2); } void Update(){ if(!avatarTargetInfo_.isShownTarget){ return; } frameCount_ = (frameCount_+1)%60; //if(frameCount_%5==0) { ProfController profCtrl=GetProfController(); if(IsSelectableAvatar(profCtrl.GetCurrentLockingPlayer())){ UpdateCurrentPlayerPos(); float px,py; hsCanvasWorldToScreenPos(avatarTargetInfo_.currentPlayerPos_,px,py); //変換した結果px=0.0,py=0.0ならば無効と言う事で、一時的にターゲットを非表示とする if(px==0.0 && py==0.0){ HideTargetCircle(); } else{ //もし一度隠されて再表示一回目ならActivateしなおす if(isHideTarget_){ ActivateTarget(); } avatarTargetInfo_.currentPos_.x=px; avatarTargetInfo_.currentPos_.y=py; DrawTargetGUI(avatarTargetInfo_.currentPos_,frameCount_==0); } }else{ DeactivateTarget(); } } } }