2023年9月14日木曜日

エンドレスランナー「ギルガメランナー」の開発日記#3

 


おはこんばんちわ!ギルガメです!

引き続き「ギルガメランナー」の開発を進めていきます!


今回はかなり雰囲気が変わりました!
やったこと:
  • プレイヤーのモデルの追加
  • プレイヤーの走りとジャンプのアニメーションの追加
  • 敵のモデルの追加
  • 敵のidleのアニメーションの追加
  • フィールドのモデルと自動生成の修正
これだけを追加して雰囲気が一気に変わりました!エンドレスランナーっぽくなりました。
WebGLでExportして試してみたのですが、少しカクツキがあったのでカメラのUpdateをLateUpdateに修正してカクツキが気にならなくなったのでよかったです。

プレイヤー、敵とフィールドのモデルはアセットストアで安くなっていた時に買ったもので、個人的に気にっているので使ってみました。
使ったアセットはこちらになります。
  • 空:AllSky Free - 10 Sky / Skybox Set(無料)
  • プレイヤー:1000+ Character Pack(有料)
  • フィールド:3D Cartoon Box Map(無料)
  • 敵:Level 1 Monster Pack(無料)

コードは複雑になってきたので詳細は載せませんが、興味のある方はコメントいただけると共有いたします。




今回の追加で難しかったこと:
  • プレイヤーのジャンプの修正、今まではOnCollisionEnterで対応していたのですが、たまに地面についていなくても地面判定できてしまい、ジャンプが2回できてしまうバグがったので、こちらをRaycastHitとPhysics.SphereCastコードで地面判定するようにしました。これで二重ジャンプの問題がなくなりました。
  • フィールドの自動生成とプレイヤーが通り過ぎた後の破壊の処理、こちらはそこまで難しくなかったのですが、プレイヤーがある程度過ぎたらフィールドを生成するロジックがうまく機能できていなかった(フィールドの生成が早くて先の先の先まで永遠に生成していた)ので、ずっと生成していると重くなる原因になるので頑張りました。
  • ステージ毎でモンスターやフィールド、時間でスピードの調整など簡単に設定できるように対応しました。
今回のバージョンは下記になります。






次はUIでも追加してみます!

最後まで読んでいただきありがとうございます!
これからもギルガメを応援していただけるよ嬉しいです!

2023年9月8日金曜日

エンドレスランナー「ギルガメランナー」の開発日記#2

 



おはこんばんちわ!ギルガメです!
引き続き「ギルガメランナー」の開発を進めていきます!


今回はもうちょっとエンドレスランナーの要素を追加していきたいので下記を対応してみました。
  • エンドレスランナー中にアイテムを拾ってポイントを稼ぐ(UIを表示)
  • エンドレスのゲームプレイのタイムを測る(UIを表示)
  • タイムによってスピードを加速して難易度を上げていく

対応したコードは下記になります。(ほとんどが追加になります)

using UnityEngine;
using UnityEngine.SceneManagement;
using TMPro;
public class GameManager : MonoBehaviour
{
public bool isGameOver = false;
public TextMeshProUGUI scoreText;
public TextMeshProUGUI timerText;
public Stage[] stages;
private bool isRunning = false;
private int score = 0;
private float startTime = 0f;
private PlayerController playerController;
private ObstacleSpawner obstacleSpawner;
private int currentStage = 0;
void Start()
{
startTime = Time.time;
isRunning = true;
playerController = GameObject.Find("Player").GetComponent<PlayerController>();
obstacleSpawner = GameObject.Find("ObstacleManager").GetComponent<ObstacleSpawner>();
}
void Update()
{
if (isGameOver)
{
RestartGame();
}
if (isRunning)
{
float elapsedTime = Time.time - startTime;
int seconds = (int)elapsedTime;
timerText.text = seconds.ToString();
if (stages.Length > currentStage && seconds > stages[currentStage].nextStage)
{
playerController.speed = stages[currentStage].PlayerSpeed;
obstacleSpawner.spawnRate = stages[currentStage].ObstacleSpeed;
currentStage++;
}
}
}
public void GameOver()
{
isGameOver = true;
}
void RestartGame()
{
SceneManager.LoadScene(SceneManager.GetActiveScene().name);
}
// ポイントを取得したらスコアを加算
public void UpdateScore(int point = 1)
{
score = score + point;
scoreText.text = score.ToString();
}
}
view raw GameManager.cs hosted with ❤ by GitHub
using UnityEngine;
public class ObstacleSpawner : MonoBehaviour
{
public GameObject obstaclePrefab;
public GameObject pointPrefab;
public float spawnRate = 2.0f;
private float spawnInterval;
void Start()
{
Invoke("SpawnObstacle", 2.0f);
}
void SpawnObstacle()
{
spawnInterval = Random.Range(0.5f, spawnRate);
if (Random.Range(0, 2) == 0) {
Instantiate(obstaclePrefab, new Vector3(Random.Range(-1, 2) * 2, Random.Range(0, 2) + 0.6f, transform.position.z), Quaternion.identity);
} else {
Instantiate(pointPrefab, new Vector3(Random.Range(-1, 2) * 2, Random.Range(0, 2) + 0.6f, transform.position.z), Quaternion.identity);
}
Invoke("SpawnObstacle", spawnInterval);
}
}
using UnityEngine;
public class PlayerController : MonoBehaviour
{
public float speed = 10.0f;
public float jumpForce = 5.0f;
private Rigidbody rb;
private int lane = 1; // 0: 左, 1: 中央, 2: 右
private Vector3[] lanePositions = { new Vector3(-2, 1, 0), new Vector3(0, 1, 0), new Vector3(2, 1, 0) };
private Vector3 targetPosition; // プレイヤーが移動する目的地
private bool isGrounded = true; // プレイヤーが地面にいるかどうか
void Start()
{
rb = GetComponent<Rigidbody>();
targetPosition = transform.position; // 初期位置を設定
}
void Update()
{
// レーン切り替え
if ((Input.GetKeyDown(KeyCode.LeftArrow) || Input.GetKeyDown(KeyCode.A)) && lane > 0)
{
lane--;
SwitchLane();
}
else if ((Input.GetKeyDown(KeyCode.RightArrow) || Input.GetKeyDown(KeyCode.D)) && lane < 2)
{
lane++;
SwitchLane();
}
// ジャンプ(地面にいる場合のみ)
if (Input.GetButtonDown("Jump") && isGrounded)
{
rb.AddForce(Vector3.up * jumpForce, ForceMode.Impulse);
isGrounded = false; // ジャンプ後は地面から離れる
}
// スムーズなレーン切り替え(X座標のみ)
Vector3 newPosition = transform.position;
newPosition.x = Mathf.Lerp(newPosition.x, targetPosition.x, speed * Time.deltaTime);
transform.position = newPosition;
// 前進(Z座標)
transform.Translate(Vector3.forward * speed * Time.deltaTime, Space.World);
}
void SwitchLane()
{
targetPosition = lanePositions[lane];
targetPosition.z = transform.position.z; // Z座標は変更しない
}
private void OnTriggerEnter(Collider other)
{
// ゲームオーバー
if (other.gameObject.tag == "Obstacle")
{
FindObjectOfType<GameManager>().GameOver();
}
// スコア加算
else if (other.gameObject.tag == "Point")
{
FindObjectOfType<GameManager>().UpdateScore();
Destroy(other.gameObject);
}
}
void OnCollisionEnter(Collision collision)
{
// 地面に触れたらisGroundedをtrueにする
if (collision.gameObject.CompareTag("Ground"))
{
isGrounded = true;
}
}
}
using System;
[Serializable]
public class Stage
{
public int nextStage = 0;
public int PlayerSpeed = 0;
public float ObstacleSpeed = 0;
}
view raw Stage.cs hosted with ❤ by GitHub

対応したことを細かく説明していきます。

  • ポイントを稼ぐ機能は障害物を生成するスクリプトと同じ機能で生成していきます。ポイント用のプレハブを作成してタグをPointに設定します。プレイヤーが接触した時にタグを確認してポイントのオブジェクトを破壊してスコアを更新します。

  • エンドレスのゲームプレイのタイムを測る、こちらはシンプルにTime.timeを使って秒数をIntに変換して更新していきます。

  • UIの表示はTextMesh Proを使っていきます。こちらの方がはっきり表示されるので万能です。デフォルトでは日本語の表示がないのでGoogle Fontsから好きなフォントをダウンロードしてTextMesh Proで対応できるようにFontを生成します。ドットのフォントが好きなのでそちらで進めていきます。

  • タイムによってスピードを加速して難易度を上げていく、こちらはStageというクラスを作成してSerializableを追加して画面上で時間の経過で難易度を設定しやすくします。

NextStage:タイムがその値を超えると反映される
PlayerSpeed:プレイヤーのスピードを加速
ObstacleSpeed:障害物の生成のDelayの短縮

上記を追加してみました。下記でV0.2でデプロイしているのでぜひ触ってみてください




次はデザインでも変えていこうかな。

最後まで読んでいただきありがとうございます!
これからもギルガメを応援していただけるよ嬉しいです!

2023年9月6日水曜日

エンドレスランナー「ギルガメランナー」の開発日記#1


 



おはこんばんちわ!ギルガメです!

引越しが落ち着いたので久々にゲームを開発していきたいと思います。

かなりのブランクがあるので簡単なエンドレスランナーのゲームを作っていきます。

できるだけコードも忘れないように記入していきたいので、もしこうした方がいいなどありましたら指摘していただけると幸いです!


今期は下記を目標に作っていきます。

簡単に遊べるエンドレスランナーの基礎の基礎を作っていきます。


まずやったこと:

  • Unityの更新 2022.3.8f1(かなり古かったので久々に更新)
  • プロジェクトの作成(モバイル用にリリース目標なので3Dモバイルで作成)
  • キャラクターの作成(PlayerController.cs)
  • 地面の作成(PlaneFollow.cs)
  • 障害物の作成(Obstacle.cs)
  • 障害物の自動生成(ObstacleSpawner.cs)
  • カメラの設定(CameraFollow.cs)
  • 障害物に直撃した場合はゲームをリセット(GameManager.cs)


次に各コードを載せていきます。まだシンプルなので細かい調整はないです。

using UnityEngine;
using UnityEngine.SceneManagement;
public class GameManager : MonoBehaviour
{
public bool isGameOver = false;
void Update()
{
if (isGameOver)
{
RestartGame();
}
}
public void GameOver()
{
isGameOver = true;
}
void RestartGame()
{
SceneManager.LoadScene(SceneManager.GetActiveScene().name);
}
}
view raw GameManager.cs hosted with ❤ by GitHub
using UnityEngine;
public class CameraFollow : MonoBehaviour
{
public Transform target; // カメラが追従する対象(プレイヤー)
public Vector3 offset; // カメラとプレイヤーの相対位置
void Update() {
// プレイヤーの位置にオフセットを加えてカメラの位置を更新
transform.position = new Vector3(transform.position.x, offset.y + offset.y, target.position.z + offset.z);
transform.LookAt(target);
}
}
view raw gistfile1.txt hosted with ❤ by GitHub
using UnityEngine;
public class Obstacle : MonoBehaviour
{
private GameObject player; // プレイヤーオブジェクト
public float threshold = -5.0f; // このZ座標を過ぎたら障害物を削除
void Start()
{
player = GameObject.Find("Player");
}
void Update()
{
// プレイヤーのZ座標よりも後ろにある(小さい)場合、障害物を削除
if (transform.position.z < player.transform.position.z + threshold)
{
Destroy(gameObject);
}
}
}
view raw Obstacle.cs hosted with ❤ by GitHub
using UnityEngine;
public class ObstacleSpawner : MonoBehaviour
{
public GameObject obstaclePrefab;
public float spawnRate = 2.0f;
private float spawnInterval;
void Start()
{
Invoke("SpawnObstacle", 2.0f);
}
void SpawnObstacle()
{
spawnInterval = Random.Range(0.5f, spawnRate);
Instantiate(obstaclePrefab, new Vector3(Random.Range(-1, 2) * 2, Random.Range(0, 2) + 0.6f, transform.position.z), Quaternion.identity);
Invoke("SpawnObstacle", spawnInterval);
}
}
using UnityEngine;
public class PlaneFollow : MonoBehaviour
{
public Transform target;
void Update() {
transform.position = new Vector3(transform.position.x, transform.position.y, target.position.z);
}
}
view raw PlaneFollow.cs hosted with ❤ by GitHub
using UnityEngine;
public class PlayerController : MonoBehaviour
{
public float speed = 10.0f;
public float jumpForce = 5.0f;
public float laneSwitchSpeed = 0.5f; // レーン切り替えの速度
private Rigidbody rb;
private int lane = 1; // 0: 左, 1: 中央, 2: 右
private Vector3[] lanePositions = { new Vector3(-2, 1, 0), new Vector3(0, 1, 0), new Vector3(2, 1, 0) };
private Vector3 targetPosition; // プレイヤーが移動する目的地
private bool isGrounded = true; // プレイヤーが地面にいるかどうか
void Start()
{
rb = GetComponent<Rigidbody>();
targetPosition = transform.position; // 初期位置を設定
}
void Update()
{
// レーン切り替え
if ((Input.GetKeyDown(KeyCode.LeftArrow) || Input.GetKeyDown(KeyCode.A)) && lane > 0)
{
lane--;
SwitchLane();
}
else if ((Input.GetKeyDown(KeyCode.RightArrow) || Input.GetKeyDown(KeyCode.D)) && lane < 2)
{
lane++;
SwitchLane();
}
// ジャンプ(地面にいる場合のみ)
if (Input.GetButtonDown("Jump") && isGrounded)
{
rb.AddForce(Vector3.up * jumpForce, ForceMode.Impulse);
isGrounded = false; // ジャンプ後は地面から離れる
}
// スムーズなレーン切り替え(X座標のみ)
Vector3 newPosition = transform.position;
newPosition.x = Mathf.Lerp(newPosition.x, targetPosition.x, laneSwitchSpeed * Time.deltaTime);
transform.position = newPosition;
// 前進(Z座標)
transform.Translate(Vector3.forward * speed * Time.deltaTime, Space.World);
}
void SwitchLane()
{
targetPosition = lanePositions[lane];
targetPosition.z = transform.position.z; // Z座標は変更しない
}
private void OnTriggerEnter(Collider other)
{
// ゲームオーバー
if (other.gameObject.tag == "Obstacle")
{
FindObjectOfType<GameManager>().GameOver();
}
}
void OnCollisionEnter(Collision collision)
{
// 地面に触れたらisGroundedをtrueにする
if (collision.gameObject.CompareTag("Ground"))
{
isGrounded = true;
}
}
}

ここからやってみたことを細かく説明していきます。
  • キャラクターの作成ではキャラクターが3方向のみ(左、中央、右)に移動できるように制御、またスムーズに動くようにLerpを使って移動できるようにしています。キャラクターが障害物に当たっ時の処理も一緒に含めています。
  • 地面の作成はキャラクターと一緒に移動するようにしています。エンドレスなので地面を固定のフィールドを作るのは大変なのでシンプルに地面もキャラクターと一緒に移動するようにしてエンドレスっぽく見せています。
  • 障害物の作成では障害物用のタグを作成してプレイヤーが避けてプレイヤーの後ろをある程度離れたら削除するように処理を入れています。
  • 障害物の自動生成はランダムのDelayタイムを設定して障害物を延々と生成するように作りました。本当にシンプルです笑
  • 障害物に直撃した場合はゲームをリセットはシンプルにゲーム全体の処理をここに入れていきます。今のところはプレイヤーが障害物に当たった場合にリセットする処理が含まれています。

上記だけで一応は遊べるぐらいのシンプルなエンドレスランナーっぽいゲームになります。ここから細かくオリジナリティを加えていければと思います。


日記のバージョン毎にWebGLで遊べるようにしていきたいのでぜひ触ってみてください!

Version 0.1




次はちょっと雰囲気でも変えていこうかな。。

最後まで読んでいただきありがとうございます!
これからもギルガメを応援していただけるよ嬉しいです!

2023年6月1日木曜日

React NativeとExpoの魅力とアプリの開発


React Nativeは、Facebookが作成したオープンソースのモバイルアプリケーションフレームワークであり、JavaScriptでAndroidとiOSアプリを作ることができます。Expoは、React Nativeのビルドや開発を支援するサービスであり、簡単に開発環境が構築できます[1][2][3].


Expoは、クロスプラットフォーム(iOS/Android/Web)でReact Nativeアプリを開発するための便利機能を集めたプラットフォームであり、素のReact Nativeプロジェクトと比較して若干の制約があるが、Expo SDKが提供する様々な機能を使えたり、開発環境の整備が簡単というメリットがあります[1].


Expoを使用すると、実機、iOS、Android両シミュレータをローカルで立ち上げてコードを編集保存したら即時反映させることができます。また、Expoアプリをインストールすることで、自分で作成したコードを実機で確認することもできます[3].


React NativeとExpoを使用してアプリを開発するには、以下の手順が必要です[1][2][3]:


1. Node.jsとnpmのインストール

2. Expo CLIのインストール

3. Expoアカウントの作成

4. 開発環境のインストール(Xcode、Android Studio、JDKなど)

5. Expoプロジェクトの作成


以上の手順を実行することで、React NativeとExpoを使用したアプリの開発環境を構築することができます。


React NativeとExpoを使用してアプリを開発することで、ネイティブアプリと同じようなユーザーエクスペリエンスを提供することができます。また、React Nativeは、Web開発で用いられるReactをもとに開発されているため、Webエンジニアでも学習コストが低いと言われています[4].


以上のように、React NativeとExpoを使用することで、簡単にクロスプラットフォームのアプリを開発することができます。


[1] https://zenn.dev/username/articles/2021-12-25-9b543d55e9ff81afff09

[2] https://rocksystem6611.hatenablog.com/entry/reactnative01

[3] https://zenn.dev/yuyaamano23/articles/dad35355a30036

[4] https://cloud.tencent.com/developer/article/1667243


React NativeとExpoを使ったアプリ開発


React Nativeは、JavaScriptのReactライブラリを利用してiOSやAndroid向けのアプリを開発することができるクロスプラットフォームのモバイルアプリケーションフレームワークです。React NativeにExpoをプラスすることで、初めてのモバイルアプリ開発にもおすすめできます。ExpoはReact Nativeを使ったアプリ開発をシンプルにしてくれるツールセットで、アプリ開発初心者にとってはデメリットよりもメリットの方が大きいとされています[1]。


React NativeとExpoを使って、以下のようなアプリを開発することができます。


- ソーシャルネットワークアプリ

- オンラインストアアプリ

- メディアアプリ

- ゲームアプリ

- ツールアプリ


React Nativeは、Reactの主な機能をReact Nativeでも同じように扱うことができます。使用言語は当然JavaScript(またはTypeScript)なので、Reactを使ったWebアプリ制作経験者であれば、学習コストは限りなく低く抑えられると思います[1].


Expoを使うことで、React Nativeアプリの開発がより簡単になります。Expoは、React Nativeアプリのビルドや開発を支援してくれるサービスで、オンラインまたはLinux、Mac、Windowsアプリとして使用することができます[2].


React NativeとExpoを使ったアプリ開発には、Node.jsの最新版が必要です。また、モバイルアプリをシミュレートするためのデバイス(スマホやタブレット等)を持っていることが前提条件となります[1].


以上のように、React NativeとExpoを使って、様々な種類のモバイルアプリを開発することができます。初めてのモバイルアプリ開発には、React NativeにExpoをプラスすることで、開発を始めるためのハードルをかなり下げることができるため、おすすめです[1]. 


参考文献

- [1] [React Native(+Expo)でモバイルアプリの開発環境を構築しよう! - Webで遊ぼ!](https://web-de-asobo.net/react-native-expo/)

- [3] [React Native Expoを利用したモバイルアプリの開発基礎 入門編 - アールエフェクト](https://reffect.co.jp/react-native/react-native-expo)

- [4] [ゼロから始める React Native + Expo 入門 - Zenn](https://zenn.dev/akira_kido/articles/9e4e8a2f6d7a9a)

- [2] [Expoでアプリを作る 【これからはじめるReact Native】 - bagelee(ベーグリー)](https://bagelee.com/programming/react-native/expo/)

2023年5月24日水曜日

Next.js 13 における最適なプラクティスとユーザーフレンドリーなライブラリの紹介


• イントロダクション 

• Next.js 13 における最適なプラクティス 

• ユーザーフレンドリーなライブラリの紹介 

• パフォーマンスチューニング 

• サンプルプロジェクトの紹介 

• 結論


イントロダクション


Next.jsは、Reactアプリケーション用のフレームワークで、サーバーサイドレンダリング、静的サイト生成、APIルート機能を提供します。Next.js 13は、Next.jsフレームワークの最新バージョンであり、Webアプリケーションをよりパフォーマンス向上させる様々な最適化機能を提供します。 

 このブログの目的は、Next.js 13の最適なプラクティスとユーザーフレンドリーなライブラリを紹介することです。読者は、サイトの最適化やパフォーマンス向上のための有用な情報を得ることができます。 React開発者にとって、Next.jsは非常に使いやすく、簡単なアプリケーションから大規模なプロジェクトまで柔軟に対応できます。Next.js 13の新しい機能には、ビルドタイムの最適化、ユーザーエクスペリエンスの改善、SEOの向上などがあります。


Next.js 13 における最適なプラクティス


イントロダクション Next.jsはReactベースのオープンソースWebアプリケーションフレームワークです。Next.js 13は、優れたユーザーエクスペリエンスを提供するためにいくつかの最適化が施されています。 このブログの目的は、Next.js 13の最適なプラクティスとユーザーフレンドリーなライブラリの紹介です。 

 Next.js 13 における最適なプラクティス Next.js 13では、静的アセットの最適化、キャッシュの最適化、サーバーサイドレンダリングの最適化が重要です。 静的アセットの最適化は、サイトの読み込み時間を短縮し、ユーザーエクスペリエンスを向上するために必要です。 Next.js 13では、Image Componentが導入され、画像の最適化が容易になりました。このComponentは、クライアントとサーバーの両方で最適な画像を自動的に選択し、表示します。 キャッシュの最適化は、サイトのパフォーマンスを向上させるために必要です。

Next.js 13では、ブラウザのキャッシュを有効にし、サイトのレスポンス時間を短縮することができます。 サーバーサイドレンダリングの最適化は、SEO最適化のために不可欠です。 Next.js 13では、ISR(Incremental Static Regeneration)が可能になり、ページの更新が柔軟になりました。これにより、検索エンジンでのサイトのランキングが改善されます。 ユーザーフレンドリーなライブラリの紹介 Next.js 13では、SWR、React Query、Framer Motionなどのユーザーフレンドリーなライブラリが導入されています。これらのライブラリは、高度なユーザーエクスペリエンスの実現に役立ちます。 SWRは、APIのフェッチングを容易にし、キャッシュと自動更新機能を提供します。React Queryは、クエリのキャッシュと並列フェッチをサポートしています。Framer Motionは、アニメーション効果を容易に追加することができ、サイトの魅力度を上げます。 パフォーマンスチューニング ビルド時間の最適化、ユーザー体験の最適化、SEOの最適化が重要です。 ビルド時間の最適化には、Vercel上でのビルド時間の短縮が役立ちます。ユーザー体験の最適化には、サイトの読み込み時間の短縮が重要です。データの最小化や、最適な画像の使用が有効です。 SEOの最適化には、重要な要素として、titleタグ、metaデータ、OG tagsがあります。これらのタグを使い、各頁ごとに適切な設定を行うことが必要です。 

 サンプルプロジェクトの紹介 Next.js 13では、シンプルなサンプルプロジェクトが用意されています。これを活用して、ローカル開発環境の構築、コンポーネントの実装方法、プロダクション環境へのデプロイ方法を学ぶことができます。 結論 Next.js 13は、高度なユーザーエクスペリエンスを提供するための最適なフレームワークです。このブログで紹介した最適なプラクティスやユーザーフレンドリーなライブラリを活用し、高性能のWebアプリケーションを開発してみてはいかがでしょうか。


ユーザーフレンドリーなライブラリの紹介


Next.js 13における最適なプラクティスとユーザーフレンドリーなライブラリの紹介の一環として、機能的で使いやすいライブラリの紹介を行います。

今回は SWR、React Query、Framer Motion に焦点を当ててみます。 

 SWRは、データのフェッチングとキャッシュ管理のための簡単な React Hooks ライブラリです。サーバーサイドレンダリング (SSR) に最適化されているため、非同期データのフェッチやキャッシュに問題が発生しないことが保証されます。なお、このライブラリにはTypeScriptサポートがあります。 

 React Query は、高速な UI レスポンスと優れたキャッシュ機能を提供するフルフィーチャーのライブラリです。このライブラリはデータの同期管理を行うための「クエリ」という概念に基づいています。また、このライブラリにはReact Nativeでも利用できるアダプターがあります。 

 Framer Motion は、シンプルな API と直感的なコンポーネントを使用して、アニメーションを簡単に作成できます。100を超えるプリセットをリリースしており、Reactとの互換性にも優れています。さらに、Framer MotionにはTypeScriptサポートがあります。 これらのライブラリは、Next.js 13で最適なパフォーマンスを発揮するように設計されており、手軽かつ効果的に使用することができます。ぜひ、プロジェクトに取り入れてみてください。


パフォーマンスチューニング


Next.js 13 における最適なプラクティスとユーザーフレンドリーなライブラリの紹介 イントロダクション Next.jsはReactフレームワークであり、Reactアプリケーションを構築するためのフルスタックソリューションです。

Next.js 13では、パフォーマンス、開発ツール、ユーザー体験に改良が入っています。このブログでは、Next.js 13の新機能と最適な開発プラクティス、ユーザーフレンドリーなライブラリ、サンプルプロジェクトの紹介を行います。  パフォーマンスチューニング ビルド時間の最適化、ユーザー体験の最適化、SEOの最適化に取り組みましょう。 ビルド時間の最適化 Next.js 13では、プリコンパイル処理があり、APIルートのコンパイル時間が短縮されます。また、プラグインやフレームワークを構成する際に、必要なライブラリのみをインストールするようにして、無駄なパッケージの読み込みを防止しましょう。 

 ユーザー体験の最適化 Next.js 13では、新しい画像コンポーネント(Image)を導入し、画像の自動最適化を行えるようになりました。 また、PrefetchやLazy Loadingを使って、ページリロードの必要性を下げ、スムーズなサイト体験を提供しましょう。 SEOの最適化 Next.js 13では、SEOのための機能を強化することができます。 サイトマップ自動生成ツールによって、情報を追加しなくても、新しいページが自動登録されます。 

さらに、Next.js 13は、ページ内のリンク先ページの内容も読み込み、SEOのポイントを解析します。 以上のエンハンスメントを活用することで、より高速でユーザーフレンドリーなサイトを構築できます。 ユーザーフレンドリーなライブラリの紹介 Next.js 13は、デフォルトでReactをベースに構築されていますが、よりユーザーフレンドリーなライブラリを使用することで、開発時間の短縮、開発効率の向上が見込めます。 以下に、いくつかのライブラリを紹介します。 SWR データのFetchやキャッシュの制御を簡素化してくれるライブラリです。リアルタイムでキャッシュの内容を更新することで、パフォーマンスを改善します。 React Query Reactアプリケーションでよく使用されるライブラリで、APIリクエストを管理するためのいくつかの問題を解決してくれます。キャッシング、再試行、オンライン/オフライン変換、並列リクエスト、アップロードなどの機能を提供しています。 Framer Motion アニメーション用のライブラリで、ユーザビリティの向上、より美しいアニメーションのインパクトを与えるために利用することができます。 

 まとめ Next.js 13では、新しい機能と最適な開発プラクティスが多く導入されました。上記の内容を理解し、利用することで、より優れたパフォーマンスのサイトを開発することができます。是非チャレンジしてみてください。


サンプルプロジェクトの紹介


サンプルプロジェクトの紹介: では、ここで実際のプロジェクトを紹介します。このプロジェクトはNext.js 13を使って作成されていて、ローカル開発環境からプロダクション環境へのデプロイまで一連のステップを模範的に実践しています。 ローカル開発環境の構築には、お気に入りのエディターとターミナルを使用して、プロジェクトをクローンしてnpm installを実行し、開発サーバーを起動するだけです!

開発サーバーはHMR(ホットモジュールリプレースメント)をサポートしており、開発を快適に行うことができます。 コンポーネントの実装方法は、Next.jsのパワフルな機能を最大限に活用しています。たとえば、自動的に生成されたページルーティングを使用して、必要なページコンポーネントを追加するだけでページを作成することができます。

また、APIルートを使用して独自のAPIエンドポイントを作成することもできます。さらに、ビルトインCSSサポートにより、CSSモジュールまたはCSS-in-JSを使用してスタイリングを完了することができます。 プロダクション環境へのデプロイには、Vercelによるデプロイメントを使用しています。

Vercelには、GitHubやBitbucketなどのバージョン管理システムと簡単に統合できる他、プラットフォームに特化した最適化が実装されています。たとえば、自動的に生成されたPWAマニフェストやnext/imageコンポーネントなどがあります。また、デプロイ時に自動的に生成されるファイルごとにCDNを使用して最適化された静的アセット最適化もあります。

 このプロジェクトの完全なコードは、GitHubリポジトリで公開されています。ぜひチェックしてみてください! 以上が、Next.js 13における最適なプラクティスとユーザーフレンドリーなライブラリの紹介のサンプルプロジェクトの実装方法です。


結論


Next.js 13は、Web開発をより簡単かつパワフルにします。 最適なプラクティスを使用することで、静的アセットやキャッシュの最適化、サーバーサイドレンダリングを行うことができます。 

さらに、SWR、React Query、Framer Motionなどのユーザーフレンドリーなライブラリがあります。 ビルド時間の最適化、ユーザー体験の最適化、SEOの最適化にも注力しました。 最後に、ローカル開発環境の構築、コンポーネントの実装方法、プロダクション環境へのデプロイ方法を紹介するサンプルプロジェクトがあります。 

全体的に、Next.js 13は、Web開発をより効率的かつスムーズにします。