Unity×Photonで、Photon.Punがusingでリンクできない問題を解決した

Photonを使っていますでしょうか。
Photonを使っている方は、リアルタイム通信のマルチプレイヤーアプリケーションを作成している方かと思います。

見よう見まねで、Photonを使い始めたのですが
Asset storeからimportして、使い始めようとしたら初っ端から躓きました。

using Photon.Pun;

これで、使い始められると書いてあるのですが、これがエラーになる。(リンクできない状態)
で、海外の情報とかを調べていくと、同じ状態で苦しんでいる方々を発見しました。(サイトどれでみたか出てこない….)

解決方法

解決方法はシンプルでした。
Unityのバージョンを変更してあげるでOKでした。

現在:2020年5月
使用したバージョン(エラーした版):2019.3.12f1

変更 したバージョン:2019.1.0f2

これで、問題なく、Photon.Punに接続することができました!!
実行タイミングによっては、違うバージョンで対応可能になっている可能性もあるかと思います。
Unityバージョンで解決可能くらいのテンションでいるといいかと思います。

Baked lightmap filtering failed. The final baked lightmap is likely to have poor quality. Try disabling the Optix denoiser or lower the lightmap resolution

Unityを利用している際に出現したエラーです。ビルドした際にでました。

Baked lightmap filtering failed. The final baked lightmap is likely to have poor quality. Try disabling the Optix denoiser or lower the lightmap resolution

何のエラーかもわからずに、
下記のUnity communityのあいだでも、解決方法分からないといった内容が出ていました。

https://forum.unity.com/threads/baked-lightmap-filtering-failed.670549/

自分も原因は分からなかったのですが、
Rendering > Lightsetting > Auto Generate
をoffにすると、エラーなくなりました。

常時ライトを照らす、みたいな設定だったかと思いますが
何か処理が重くなってしまっていたのでしょうか…!!

Unityで特定のObjectに接触している物体を触れて×アクション(取得Keydown)をした際にのみGETする方法

触れている物体をGETする方法を記載していきたいと思います。
あまり有効な記事ではない可能性もあります!
自分の備忘録的に書いていきたいと思います。

やりたいことは、
特定のObjectに接触している物体を触れて×アクション(取得Keydown)をした際にのみGETする、といった具合です。

色々やり方があるかと思いますが
今回、重要な要素としたい部分は、接触しているObjectの名称をデータとして保持するということです。

// now touchの変数を作成
string nowTouch;

void Update() {     

 // keydown Space がクリックされたときのみ発火
 if (Input.GetKeyDown(KeyCode.Space)) {         

  //  now touch の変数に合わせて処理を変更
  if (nowTouch== "Cube") {             
  } else if (nowTouch== "Box") {
  } else if (nowTouch == "Sphere"){ 
  }
 }
}

 //  接触した際に、接触したObjectを nowTouch へ代入
private void OnTriggerEnter(Collider other) {     
nowTouch = other.name;     
}

  //  接触が離れた後に、nowTouch を空へ
void OnTriggerExit(Collider other) {     
nowTouch = "";     
}

UnityのStart以前でのデータ処理順番

今回はふと、気になったことを、書いていきます。
UnityのEvent処理順番は下記のように記載されています。

https://docs.unity3d.com/jp/460/Manual/ExecutionOrder.html

ここで、理解できなかったのが、Inspector上でのデータセットが順番にどう影響するのかです。

今回、3パターンでのデータセットが順番としてどんな影響を及ばすのかを調べました。

パターン1:class内のグローバルエリア(start , updateでも無いエリア)
パターン2:inspectorでのデータ設定
パターン3:Start 内のデータ設定

public class test : MonoBehaviour
 {
  // パターン1
 public int No = 15; 

void Start() {  
   // パターン3
   No = 15;
 }

 void Update()
     {
         Debug.Log(No);
     }
 }

結果は、
パターン1 → パターン2 → パターン3の順番で処理されていました。
inspectorで設定したNo変数の値は、StartでNo変数が上書きされます。

UnityでLightが常にPlayerを照らしてくれる設定

以前、FPS視点のCameraワークを設定するコードを書きました。
このコードを利用すれば同じ考え方でLightも動かすことが可能です。

前回、 Playerの子階層に、新しくGameObject cameraFollow を作成しました。
今回は、cameraFollowに対して、Lightを紐づけていきます。
と、いうのも常に、Playerの後ろ側から光が照らされる状態を作ります。

void Update() {     

\\cameraFolowのy軸15f, z軸3fのpositionへ
transform.position = GameObject.Find(" cameraFollow ").transform.position + new Vector3(0,15f,3f); 
    
 \\Lightは常にPlayerの方向を向くようへ
 transform.LookAt(GameObject.Find("Player").transform); 
}

UnityのCanvasを活用して、HPのゲージを作成

以前、HPの減少を扱うscriptを作成する記事を書きました。

この変化するHPをゲージとして、画面上に表示していきたいと思います。
CanvasのSliderを使います。

大まかな流れ
(1):Sliderの配置
(2):SliderのValueにデータを反映するscriptを作成
(3):HPのデータと、Sliderのデータを接続

(1):Sliderの配置

hierarchyで、
Create > UI > Canvasを
Canvasの子階層にて
Create > UI > Sliderを選択してください。

POSX・POSYで好きな場所へSliderを合わせてください。
(Canvas・Sliderの細かい説明は省きます。)

最終的にやりたいことは、SliderのValueにHPを反映していくことです。

(2):SliderのValueにデータを反映するscriptを作成

CanvasにAdd Component でscriptをNew作成する。
(名称を PlayerUI とする)

public class PlayerUI : MonoBehaviour
 {
     public Slider slider;

public void first(int maxHP) {     
//maxValueとValueを初期設定
slider.maxValue = maxHP;     
slider.value = maxHP; 
} 

public void HPUpdate(int HP) { 
 //ここでvalueを反映
slider.value = HP; 
}

}

※CanvasのInspectorにて、表示されているSliderと、hierarchy上のsliderを紐づけ忘れずに

(3):HPのデータと、Sliderのデータを接続

前回の記事の
private void updateHP(float deltaHPacc) 関数に追記していきます。

public class PlayerManage : MonoBehaviour
 {
public PlayerUI playerUI;


\\上記記事で作成した関数
private void updateHP(float deltaHPacc) {
 HPacc -= deltaHPacc;     
 HP = Mathf.RoundToInt(HPacc);     

\\ PlayerUIHPUpdateメソッドを呼び出している
     playerUI.HPUpdate(HP);
 
 }


}

public PlayerUIをCanvas( PlayerUI scriptが紐づいているオブジェクト)と紐づけること。

UnityでPlayerが動く度にHPが減少していく機能の作成

以前、FPS視点で動くPlayerを制御する方法を紹介しました。

移動しているときのみに、HPを減少させたいので
velocityを使っていきます。
velocity.magnitudeというパラメータを使うことで、velocityの大きさを取得することができます。

 private Rigidbody rb;

void Update()
{
// ココから 以前の記事で紹介した動く操作方法
float x = Input.GetAxis("Horizontal");
float z = Input.GetAxis("Vertical");
transform.Rotate(0,x,0, Space.World);
float angleY = (360 - transform.eulerAngles.y + 90) % 360;
float radian = angleY * Mathf.Deg2Rad;     
float sin = Mathf.Sin(radian);     
float cos = Mathf.Cos(radian);     
rb.velocity = new Vector3(cos, 0, sin) * z;
// ココまで 以前の記事で紹介した動く操作方法 

// velocityが動いているときのみ処理する 
if (rb.velocity.magnitude > 0)     
{         
 // velocityの大きさを引数にした関数を作成
updateHP(rb.velocity.magnitude);     
}

}


private void updateHP(float deltaHPacc) {
\\floatでHPを減少させていき
HPacc -= deltaHPacc;     
 \\intへキャスト
 HP = Mathf.RoundToInt(HPacc);     

}
 

C#で、計算は小数点・表示は整数を実現する方法

どういったシチュエーションを想定しているかというと
HP 100 から減少していくが、整数で減少するよりももっと細かい減少を表現したいときなどです。

//floatで減少
HPfloat -= deltaHPacc;     

\\最大値は越えずに,0以下にもならない
if ( HPfloat  >= (float)maxHP)     
{ HPfloat  = (float)maxHP;     } 
else if ( HPfloat  <= 0f)
{ HPfloat  = 0;     }   

//整数に変換
HP = Mathf.RoundToInt(HPacc);

Unity positionの1つだけを変更する方法

今回は、position(Vector3 (x, y, z))の1つの要素だけを変更する方法を紹介します。

非常に簡単です。

        Vector3 pos = transform.position;
        pos.y = 0.1f;
        transform.position = pos;

y座標のみを変更するコードを記載しました。
positionを変更したい場合には、positionのデータ型で代入してあげる必要があります。( Vector3 (x, y, z) を想定)。
なので、下記のように1つのデータのみを選択して、代入することは出来ません。

//これは出来ない!!
transform.position.y = 0.1f;

prefabを一定時間間隔で生成する方法

今回は、Unityでのゲーム作りでは欠かせないprefabについてお話していきます。

( 1 ):一定時間間隔で処理を実行する
( 2 ):prefabを生成する

( 1 ):一定時間間隔で処理を実行する

幾つか、豊富はあるようですが
一番簡単そうな処理は、 InvokeRepeating 関数をです。

InvokeRepeating("UpdateMakePrefab", START, INTERVAL);

#UpdateMakePrefab → 繰り返し処理を実行したいメソッド名
#START → 一番最初に起動する時間
#INTERVAL → 更新する時間間隔

( 2 ):prefabを生成する

prefabを生成する関数は
Instantiate()という関数を使います。

Instantiate(prefabオブジェクト, prefabのposition, prefabの向き);

一定時間間隔で、prefabを生成するコード最後にまとめたいと思います。

 using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 
 public class makePrefab : MonoBehaviour
 {
     // public でInspectorから、生成したいprefabを紐付けておきます。
     public GameObject makeprefab;

     private const float START = 0.0f;
     private const float INTERVAL = 5.0f;
 
     void Start()
     {         InvokeRepeating("UpdateMakePrefab", START, INTERVAL);
     }
  
 
     private void UpdateMakePrefab() {

Instantiate(makeprefab, new Vector3(Random.Range(-5.0f, 5.0f),0, Random.Range(-5.0f, 5.0f)), Quaternion.identity);
     }
 
 }